【问题标题】:StAX XML all content between two required tagsStAX XML 两个必需标签之间的所有内容
【发布时间】:2012-12-12 16:20:15
【问题描述】:

开始学习StAX,使用XMLStreamReader,我遇到了一些问题。如何将标签之间的所有内容作为文本获取?我的意思是,我知道所需标签的名称,当我找到它时,我必须转到关闭标签,并且我在它们之间找到的所有内容都必须附加到某个字符串。 例如,我们有类似

<rootTag>
...    
    <someTag>
        Some text content and other tags here…
    </someTag >
    <tagINeed>
        <someinternalTag1>
            <someinternalTag11>
                Some text content..
            </someinternalTag11>
            ...
        </someinternalTag1>
        <someinternalTag2>
            Something here
        </someinternalTag2>
    </tagINeed>
...
    <somethingAnother>
...
    </somethingAnother >
...
</rootTag>    

所以,我需要得到我的字符串

        <someinternalTag1>
            <someinternalTag11>
                Some text content..
            </someinternalTag11>
            ...
        </someinternalTag1>
        <someinternalTag2>
            Something here
        </someinternalTag2>

我怎样才能得到它?也许,我必须在源xml中找到所需块的开始和结束偏移量,并在解析后给出子字符串?

【问题讨论】:

    标签: java xml xml-parsing stax xmlstreamreader


    【解决方案1】:

    试试

        StringWriter sw = new StringWriter();
        XMLOutputFactory of = XMLOutputFactory.newInstance(); 
        XMLEventWriter xw = null;
        XMLInputFactory f = XMLInputFactory.newInstance();
        XMLEventReader xr = f.createXMLEventReader(new FileInputStream("test.xml"));
        while (xr.hasNext()) {
            XMLEvent e = xr.nextEvent();
            if (e.isStartElement()
                    && ((StartElement) e).getName().getLocalPart().equals("tagINeed")) {
                xw = of.createXMLEventWriter(sw);
            } else if (e.isEndElement()
                    && ((EndElement) e).getName().getLocalPart().equals("tagINeed")) {
                break;
            } else if (xw != null) {
                xw.add(e);
            }
        }
        xw.close();
        System.out.println(sw);
    

    打印

        <someinternalTag1>
            <someinternalTag11>
                Some text content..
            </someinternalTag11>
        </someinternalTag1>
        <someinternalTag2>
            Something here
        </someinternalTag2>
    

    更新:

    如果你也需要XML字符串,我们可以这样写:

            if (e.isStartElement() &&
                    ((StartElement) e).getName().getLocalPart().equals("tagINeed")){
                xw = of.createXMLEventWriter(sw);
                xw.add(e);
            } else if (e.isEndElement() &&
                    ((EndElement) e).getName().getLocalPart().equals("tagINeed")){
                xw.add(e);
                break;
            } else if (xw != null) {
                xw.add(e);
            }
    

    【讨论】:

    • 但它输出 [Stax Event #4][Stax Event #1][Stax Event #4][Stax Event #1][Stax Event #4][Stax Event #2][Stax Event #4][Stax 事件 #2][Stax 事件 #4][Stax 事件 #1][Stax 事件 #4][Stax 事件 #2][Stax 事件 #4]
    • 嗯,输出是真实的。我的 StAX 是 Java 7 内部 com.sun.xml.internal.stream.XMLInputFactoryImpl。你的 StAX 是什么?
    • 不管怎样,试试我的更新版本,它不依赖于 StAX impl
    • e- 只是事件的类型。我的问题是如何将当前位置的内容作为文本获取,而不检查类型。因为不做 if(e == XMLStreamConstants.START_ELEMENT){ System.out.println(""); } else if(e == XMLStreamConstants.END_ELEMENT){ System.out.println("" + reader.getLocalName() + ">"); } else if(e == XMLStreamConstants.CHARACTERS){ System.out.println(reader.getText()); }
    • 对不起,不明白.. 我必须从 com.sun.xml.internal.stream 导入 XMLInputFactory?但是这个包里没有这样的类...请问您可以在这里发布完整的程序文本,带有“导入”部分吗?
    【解决方案2】:

    E. Dorofeev 的解决方案很好,但是如果有同名的内部标签就失败了。我添加了一个计数器。

    String fichier="test_stax_2.txt";
    
    String tag="tagINeed";
    int count=0;
    
    StringWriter sw = new StringWriter();
    XMLOutputFactory of = XMLOutputFactory.newInstance(); 
    XMLEventWriter xw = null;
    XMLInputFactory f = XMLInputFactory.newInstance();
    XMLEventReader xr = f.createXMLEventReader(new FileInputStream(fichier));
    
    while (xr.hasNext())
        {
        XMLEvent e = xr.nextEvent();
        if (e.isStartElement()
                && ((StartElement) e).getName().getLocalPart().equals(tag))
            {
            if (count==0)
                xw = of.createXMLEventWriter(sw);
            else
                xw.add(e);
            count++;
            } 
    
        else if (e.isEndElement()
                && ((EndElement) e).getName().getLocalPart().equals(tag))
            {
            count --;
            if (count==0)
                break;
            else
                xw.add(e);
            } 
            else if (xw != null) 
            {
            xw.add(e);
            }
    }
    if (xw!=null)
       xw.close();
    
    System.out.println(sw);
    

    【讨论】:

      【解决方案3】:

      在 XML 中,一切都是一个节点,STAX 使您能够逐个遍历这些节点。 我认为可以通过将 XML 转换为字符串,然后使用 Transformer 搜索所需的字符串来获得您想要的结果。

      Transformer t=TransformerFactory.newInstance().newTransformer();
      StringWriter sw=new StringWriter();         
      StreamResult result=new StreamResult(sw);//holds the result of a transformation
      DOMSource d=new DOMSource(XMLdoc);//your XML document
      t.transform(d, result);
      String xmlstring=sw.toString();
      

      您可以使用 xmlstring 来获得所需的结果。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-06
        • 1970-01-01
        • 1970-01-01
        • 2016-04-06
        • 1970-01-01
        • 1970-01-01
        • 2012-10-25
        • 1970-01-01
        相关资源
        最近更新 更多