在使用Stax和xslt递归读取xml文件时,我只获得第一次迭代数据。它不会转移到下一个。
以下是我的示例xml数据:
myBinary.exe ... | Tee-Object ...
这是我的示例xslt文件:
<Root node>
<ParentNode>
<ChildNode1 a1, a2, a3,a4 ...>
<SubChild1 b1, b2, b3, b4 ../>
<SubChild2 c1, c2, c3, c4 ../>
<SubChild3 d1, d2, d3, d4 ..>
<GrandChild1 e1, e2, e3, e4 ../>
<GrandChild2 f1, f2, f3, f4 ../>
<GrandChild3 g1, g2, g3, g4 ../>
</SubChild3>
<ChildNode1>
<ChildNode2 h1, h2, h3 ...>
<SubChild4 i1, i2, i3 ...>
<GrandChild4 j1, j2, j3 .../>
<GrandChild5 k1, k2, k3 .../>
</SubChild4>
<SubChild5>
<GrandChild6>
<GreatGrandChild1 l1, l2, l3 ../>
</GrandChild6>
</SubChild5>
</ChildNode2>
<ChildNode2 h1, h2, h3 ...>
<SubChild4 i1, i2, i3 ...>
<GrandChild4 j1, j2, j3 .../>
<GrandChild5 k1, k2, k3 .../>
</SubChild4>
<SubChild5>
<GrandChild6>
<GreatGrandChild1 l1, l2, l3 ../>
</GrandChild6>
</SubChild5>
</ChildNode2>
<ChildNode2 h1, h2, h3 ...>
<SubChild4 i1, i2, i3 ...>
<GrandChild4 j1, j2, j3 .../>
<GrandChild5 k1, k2, k3 .../>
</SubChild4>
<SubChild5>
<GrandChild6>
<GreatGrandChild1 l1, l2, l3 ../>
</GrandChild6>
</SubChild5>
</ChildNode2>
.
.
.
<ChildNode2>
. . . .
</ChildNode2>
------ This is 1 iteration from ChildNode1 to Chn ------
<ChildNode1 a1, a2, a3,a4 ...>
<SubChild1 b1, b2, b3, b4 ../>
<SubChild2 c1, c2, c3, c4 ../>
<SubChild3 d1, d2, d3, d4 ..>
<GrandChild1 e1, e2, e3, e4 ../>
<GrandChild2 f1, f2, f3, f4 ../>
<GrandChild3 g1, g2, g3, g4 ../>
</SubChild3>
<ChildNode1>
<ChildNode2 h1, h2, h3 ...>
<SubChild4 i1, i2, i3 ...>
<GrandChild4 j1, j2, j3 .../>
<GrandChild5 k1, k2, k3 .../>
</SubChild4>
<SubChild5>
<GrandChild6>
<GreatGrandChild1 l1, l2, l3 ../>
</GrandChild6>
</SubChild5>
</ChildNode2>
<ChildNode2 h1, h2, h3 ...>
<SubChild4 i1, i2, i3 ...>
<GrandChild4 j1, j2, j3 .../>
<GrandChild5 k1, k2, k3 .../>
</SubChild4>
<SubChild5>
<GrandChild6>
<GreatGrandChild1 l1, l2, l3 ../>
</GrandChild6>
</SubChild5>
</ChildNode2>
<ChildNode2 h1, h2, h3 ...>
<SubChild4 i1, i2, i3 ...>
<GrandChild4 j1, j2, j3 .../>
<GrandChild5 k1, k2, k3 .../>
</SubChild4>
<SubChild5>
<GrandChild6>
<GreatGrandChild1 l1, l2, l3 ../>
</GrandChild6>
</SubChild5>
</ChildNode2>
.
.
.
<ChildNode2>
. . . .
</ChildNode2>
------ This is 2 iteration from ChildNode1 to Chn ------
<ChildNode1 a1, a2, a3,a4 ...>
<SubChild1 b1, b2, b3, b4 ../>
<SubChild2 c1, c2, c3, c4 ../>
<SubChild3 d1, d2, d3, d4 ..>
<GrandChild1 e1, e2, e3, e4 ../>
<GrandChild2 f1, f2, f3, f4 ../>
<GrandChild3 g1, g2, g3, g4 ../>
</SubChild3>
<ChildNode1>
<ChildNode2 h1, h2, h3 ...>
<SubChild4 i1, i2, i3 ...>
<GrandChild4 j1, j2, j3 .../>
<GrandChild5 k1, k2, k3 .../>
</SubChild4>
<SubChild5>
<GrandChild6>
<GreatGrandChild1 l1, l2, l3 ../>
</GrandChild6>
</SubChild5>
</ChildNode2>
<ChildNode2 h1, h2, h3 ...>
<SubChild4 i1, i2, i3 ...>
<GrandChild4 j1, j2, j3 .../>
<GrandChild5 k1, k2, k3 .../>
</SubChild4>
<SubChild5>
<GrandChild6>
<GreatGrandChild1 l1, l2, l3 ../>
</GrandChild6>
</SubChild5>
</ChildNode2>
<ChildNode2 h1, h2, h3 ...>
<SubChild4 i1, i2, i3 ...>
<GrandChild4 j1, j2, j3 .../>
<GrandChild5 k1, k2, k3 .../>
</SubChild4>
<SubChild5>
<GrandChild6>
<GreatGrandChild1 l1, l2, l3 ../>
</GrandChild6>
</SubChild5>
</ChildNode2>
.
.
.
<ChildNode2>
. . . .
</ChildNode2>
------like this we have n number of Iterations------
</ParentNode>
</Root node>
这是我的Java代码:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:x="http://www.fixprotocol.org/FIXML-5-0-SP2"
xsi:schemaLocation="http://www.fixprotocol.org/FIXML-5-0-SP2 fixml-main-5-0-SP2_.xsd"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math">
<xsl:mode streamable="yes"/>
<xsl:output method="text" encoding="utf-8" />
<xsl:param name="delim" select="'|'" />
<xsl:param name="break" select="'
'" />
<xsl:template match="/">
<xsl:text> a1 | a2| d1| d2| e1| e2| f1| f2| h1| h2| h3| j1| j2| k1| k2| l1 </xsl:text>
<xsl:text>
</xsl:text>
<xsl:apply-templates select="descendant::x:ParentNode"/>
</xsl:template>
<xsl:template match="x:ParentNode">
<xsl:value-of select="concat( normalize-space(x:ChildNode1/@a1))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode1/@a2))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode1/x.SubChild3/@d1))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode1/x.SubChild3/@d2))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode1/x.SubChild3/x.GrandChild1/@e1))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode1/x.SubChild3/x.GrandChild1/@e2))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode1/x.SubChild3/x.GrandChild2/@f1))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode1/x.SubChild3/x.GrandChild2/@f2))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode2/x:SubChild4/@h1))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode2/x:SubChild4/@h2))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode2/x:SubChild4/@h3))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode2/x:SubChild4/x:GrandChild4/@j1))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode2/x:SubChild4/x:GrandChild4/@j2))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode2/x:SubChild4/x:GrandChild5/@k1))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode2/x:SubChild4/x:GrandChild5/@k2))" /><xsl:value-of select="$delim" />
<xsl:value-of select="concat( normalize-space(x:ChildNode2/x:SubChild5/x.GrandChild6/x.GreatGrandChild1/@l1))" /><xsl:value-of select="$delim" />
</xsl:template>
</xsl:stylesheet>
输出:
public class Xml2Csv {
public static int transform(InputStream is, OutputStream os, Transformer transformer, QName name) throws XMLStreamException, TransformerException {
long time1 = System.nanoTime();
// Open input & output files
XMLInputFactory factory = XMLInputFactory.newInstance();
factory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, true);
factory.setProperty(XMLInputFactory.IS_VALIDATING, false);
XMLStreamReader reader = factory.createXMLStreamReader(is);
// In case you want to check which implementation is used.
// Woodstox is a bit faster, but not worth adding extra dependency.
// System.out.println("Reader="+reader);
// System.out.println("Transformer="+transformer);
Result result = new StreamResult(os);
int count = 0;
while (reader.hasNext()) {
if (reader.getEventType() == XMLStreamReader.START_ELEMENT && name.equals(reader.getName())) {
// System.out.println("FOUND " + count);
count++;
transformer.transform(new StAXSource(reader), result);
if (count % 1000 == 0) {
long time2 = System.nanoTime();
double ms = (time2 - time1) / 1000000.0;
System.out.format("Time=%.2fms Rows=%d%n", ms, count);
}
} else if (reader.getEventType() == XMLStreamReader.START_ELEMENT) {
// System.out.println("Start "+reader.getName()+" != "+name);
}
reader.next();
}
long time2 = System.nanoTime();
double ms = (time2 - time1) / 1000000.0;
System.out.format("Total Time=%.2fms Total rows=%d%n", ms, count);
return count;
}
public static void main(String arg[]) throws Exception {
// Parse command line options
File xsltFile;
File inputFile;
File outputFile;
String tagName;
String namespace;
try {
String xsltFileName = parse("-x", arg, "XSLT sheet", true);
String inputFileName = parse("-f", arg, "Input file", true);
String outputFileName = parse("-o", arg, "Output file", true);
tagName = parse("-t", arg, "Tag name", true);
namespace = parse("-n", arg, "Tag Namespace URL", false);
xsltFile = new File(xsltFileName);
inputFile = new File(inputFileName);
outputFile = new File(outputFileName);
} catch (ParseException e) {
System.err.println(e.getMessage());
System.err.println("Syntax: Xml2Csv -f <input file> -o <output file> -x <XSLT stylesheet> -t <Tag name> [-n <namespace URL>]");
System.err.println("Will split given file on given tag with given namespace.");
System.err.println("Will process contents of each tag using given XSLT.");
System.exit(1);
return;
}
if (!xsltFile.exists()) {
System.err.println("File not found " + xsltFile.getAbsolutePath());
System.exit(1);
}
if (!inputFile.exists()) {
System.err.println("File not found " + inputFile.getAbsolutePath());
System.exit(1);
}
// Open XSLT stylesheet
StreamSource stylesource = new StreamSource(xsltFile);
Transformer transformer = TransformerFactory.newInstance().newTransformer(stylesource);
// Create XML tag name which is used to break up XML into rows
final QName name;
if (namespace != null) {
name = new QName(namespace, tagName);
} else {
name = new QName(tagName);
}
System.out.println("Will look for tag " + name + " in namespace " + namespace);
FileOutputStream fos = null;
FileInputStream fis = null;
try {
// Open input & output files
fis = new FileInputStream(inputFile);
fos = new FileOutputStream(outputFile);
transform(fis, fos, transformer, name);
} finally {
if (fos != null) {
fos.close();
}
if (fis != null) {
fis.close();
}
}
}
// Teo - inefficient, but who cares
private static String parse(String option, String[] arg, String desc, boolean required) throws ParseException {
for (int i = 0; i < arg.length; i++) {
if (option.equals(arg[i])) {
if (i + 1 < arg.length) {
String value = arg[i + 1].trim();
return value;
} else {
throw new ParseException(option + " must be followed by an argument", i);
}
}
}
if (required) {
throw new ParseException(desc + " is required", 0);
} else {
return null;
}
}
}
我应该获得所有迭代数据,但我只得到一个迭代数据。
你们可以帮助我在哪里可以更改代码以获取所有迭代数据?