在使用Stax和xslt递归解析xml时遇到问题

时间:2017-11-28 03:37:16

标签: java xml xslt stax

在使用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="'&#xA;'" />



  <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>&#xA;</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;
    }
}
}

我应该获得所有迭代数据,但我只得到一个迭代数据。

你们可以帮助我在哪里可以更改代码以获取所有迭代数据?

0 个答案:

没有答案
相关问题