【问题标题】:End element isn't detected by StaxStax 未检测到结束元素
【发布时间】:2025-12-31 18:35:01
【问题描述】:

我正在读取一个 XML 文件,如下所示:

<ts>
    <tr comment="" label="tr1">
        <node order="1" label="" />
    </tr>
</ts>

我预计下面的代码会在屏幕上打印出三个e

XMLInputFactory factory = XMLInputFactory.newInstance();
XMLStreamReader sr = factory.createXMLStreamReader(new FileReader("test.xml"));

while (sr.hasNext()) {
    int eventType = sr.next();

    if (eventType == XMLStreamReader.START_DOCUMENT) {
        continue;
    } else if (eventType == XMLStreamReader.END_ELEMENT) {
        System.out.println("e");
    } else if (eventType == XMLStreamReader.START_ELEMENT) {
        System.out.println("s");
    }
}

但它不起作用!关于如何解决问题的任何想法?

注意:我认为是和self-closed-tags有关,例如:&lt;myTag id="1" /&gt;

【问题讨论】:

    标签: java xml stax


    【解决方案1】:

    您问题中发布的代码为我生成了三个e,这是预期的。我在 Mac 上使用 JDK 1.6。

    演示

    您可能想尝试运行以下代码来查看您缺少哪个结束元素事件:

    import java.io.FileReader;
    import javax.xml.stream.*;
    
    public class Demo {
    
        public static void main(String[] args) throws Exception {
            XMLInputFactory factory = XMLInputFactory.newInstance();
            XMLStreamReader sr = factory.createXMLStreamReader(new FileReader("test.xml"));
            System.out.println(sr.getClass());
    
            while (sr.hasNext()) {
                int eventType = sr.next();
    
                if (eventType == XMLStreamReader.START_DOCUMENT) {
                    continue;
                } else if (eventType == XMLStreamReader.END_ELEMENT) {
                    System.out.println("End Element:    " + sr.getLocalName());
                } else if (eventType == XMLStreamReader.START_ELEMENT) {
                    System.out.println("Start Element:  " + sr.getLocalName());
                }
            }
        }
    
    }
    

    输出

    下面是我得到的输出。

    class com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl
    Start Element:  ts
    Start Element:  tr
    Start Element:  node
    End Element:    node
    End Element:    tr
    End Element:    ts
    

    【讨论】:

    • 如果 System.out.println(sr.getLocalName())END_ELEMENT 的 if 块内会发生什么?
    • 它不会进入 END_ELEMENT 块 - 它永远不会满足 if (eventType == XMLStreamReader.END_ELEMENT)
    • 哦!这是一个毫无意义的问题,至少您的测试确保我的问题不在我的 stax 解析中。
    【解决方案2】:

    我在使用 JDK 1.7 的 Windows 上得到与 Blaise Doughan 相同的结果:

    s
    s
    s
    e
    e
    e
    

    我认为这与&lt;node order="1" label="" /&gt; 无关,因为documentation 声明:

    注意:空元素(如&lt;tag/&gt;)会报两个 单独的事件:START_ELEMENTEND_ELEMENT - 这会保留解析 空元素与&lt;tag&gt;&lt;/tag&gt; 的等效性。这个方法会抛出一个 IllegalStateException 如果在 hasNext() 之后调用,则返回 false。

    远射:也许其他一些相关代码可能会导致奇怪的行为?

    【讨论】: