我有很大的XML文件(介于500MB和1GB之间),并且我试图对其进行过滤,以便仅保留具有某些指定属性的节点,在本例中为 Prod_id 。 我大约需要过滤1万个Prod_id,目前XML包含约6万个项目。
当前,我正在将XSL与node.js(https://github.com/fiduswriter/xslt-processor)配合使用,但是它的运行速度非常慢(我从未见过其中一个在30-40分钟之内完成)。
是否可以提高此过程的速度? XSL不是必需的,我可以使用所有东西。
XML示例:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<products>
<Product Quality="approved" Name="WL6A6" Title="BeBikes comfort WL6A6" Prod_id="BBKBECOMFORTWL6A6">
<CategoryFeatureGroup ID="10030">
<FeatureGroup>
<Name Value="Dettagli tecnici" langid="5"/>
</FeatureGroup>
</CategoryFeatureGroup>
<Gallery />
</Product>
...
<Product Quality="approved" Name="WL6A6" Title="BeBikes comfort WL6A6" Prod_id="LAL733">
<CategoryFeatureGroup ID="10030">
<FeatureGroup>
<Name Value="Dettagli tecnici" langid="5"/>
</FeatureGroup>
</CategoryFeatureGroup>
<Gallery />
</Product>
</products>
我正在使用的XSL
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="
products/Product
[not(@Prod_id='CEESPPRIVAIPHONE4')]
...
[not(@Prod_id='LAL733')]"
/>
</xsl:stylesheet>
谢谢
答案 0 :(得分:1)
我使用类似于此答案https://stackoverflow.com/a/13851518/1152049
的方法解决了问题谢谢
private static void filter(InputStream fileInputStream, final Set<String> prodIdToExclude) throws SAXException, TransformerException, FileNotFoundException {
XMLReader xr = new XMLFilterImpl(XMLReaderFactory.createXMLReader()) {
private boolean skip;
@Override
public void startElement(String uri, String localName, String qName, Attributes atts)
throws SAXException {
if (qName.equals("Product")) {
String prodId = atts.getValue("Prod_id");
if (prodIdToExclude.contains(prodId)) {
skip = true;
} else {
super.startElement(uri, localName, qName, atts);
skip = false;
}
} else {
if (!skip) {
super.startElement(uri, localName, qName, atts);
}
}
}
public void endElement(String uri, String localName, String qName) throws SAXException {
if (!skip) {
super.endElement(uri, localName, qName);
}
}
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
if (!skip) {
super.characters(ch, start, length);
}
}
};
Source src = new SAXSource(xr, new InputSource(fileInputStream));
Result res = new StreamResult(new FileOutputStream("output.xml"));
TransformerFactory.newInstance().newTransformer().transform(src, res);
}