Java XMLStreamReader如何使用相同类型的嵌套元素

Java XMLStreamReader如何使用相同类型的嵌套元素,java,xml,xmlstreamreader,Java,Xml,Xmlstreamreader,我正在使用XMLStreamReader并解析以下XML: <root> <element> <attribute>level0</attribute> <element> <attribute>level1</attribute> <element> <attribute&g

我正在使用XMLStreamReader并解析以下XML:

<root>
    <element>
        <attribute>level0</attribute>
        <element>
            <attribute>level1</attribute>
            <element>
                <attribute>level2</attribute>
            </element>
        </element>
    </element>
</root>
不幸的是,当我使用
reader.next()到达第一个结束元素标记时,我得到以下异常:

javax.xml.stream.XMLStreamException: ParseError at [row,col]:[7,14]
Message: XML document structures must start and end within the same entity. 
有没有办法覆盖XMLStreamReader的默认行为来解决这个问题

编辑

以下是我正在使用的代码:

@Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, Text>.Context context)
        throws IOException, InterruptedException {
    String document = value.toString();
    System.out.println("'" + document + "'");
    try {
        XMLStreamReader reader = XMLInputFactory.newInstance().createXMLStreamReader(
                new ByteArrayInputStream(document.getBytes()));
        String propertyName = "";
        String propertyValue = "";
        String currentElement = "";
        while (reader.hasNext()) {
            int code = reader.next();
            switch (code) {
            case START_ELEMENT:
                currentElement = reader.getLocalName();
                break;
            case CHARACTERS:
                if (currentElement.equalsIgnoreCase("element")) {
                    propertyName += reader.getText();
                } else if (currentElement.equalsIgnoreCase("attribute")) {
                    propertyValue += reader.getText();
                }
                break;
            }
        }
        reader.close();
        context.write(new Text(propertyName.trim()), new Text(propertyValue.trim()));
    } catch (Exception e) {
        e.printStackTrace();
    }
}
@覆盖
受保护的void映射(LongWritable键、文本值、Mapper.Context)
抛出IOException、InterruptedException{
字符串文档=value.toString();
System.out.println(““+”文档+“”);
试一试{
XMLStreamReader reader=XMLInputFactory.newInstance().createXMLStreamReader(
新建ByteArrayInputStream(document.getBytes());
字符串propertyName=“”;
字符串propertyValue=“”;
字符串currentElement=“”;
while(reader.hasNext()){
int code=reader.next();
开关(代码){
案例开始元素:
currentElement=reader.getLocalName();
打破
大小写字符:
if(currentElement.equalsIgnoreCase(“元素”)){
propertyName+=reader.getText();
}else if(currentElement.equalsIgnoreCase(“属性”)){
propertyValue+=reader.getText();
}
打破
}
}
reader.close();
write(新文本(propertyName.trim()),新文本(propertyValue.trim());
}捕获(例外e){
e、 printStackTrace();
}
}

示例XML文档和/或StAX解析器没有问题,可以通过以下代码检查:

@Test
public void testSO_31815379() throws XMLStreamException, UnsupportedEncodingException {
    final String xml = 
        "<root>\n" +
        "    <element>\n" +
        "        <attribute>level0</attribute>\n" +
        "        <element>\n" +
        "            <attribute>level1</attribute>\n" +
        "            <element>\n" +
        "                <attribute>level2</attribute>\n" +
        "            </element>\n" +
        "        </element>\n" +
        "    </element>\n" +
        "</root>";

    final XMLStreamReader reader = XMLInputFactory.newInstance()
        .createXMLStreamReader(new ByteArrayInputStream(xml.getBytes("UTF-8")));
    LOG.info("Using XMLStreamReader implementation: %s", reader.getClass().getName());

    reader.require(XMLStreamConstants.START_DOCUMENT, null, null);
    int event;
    while ((event = reader.next()) != XMLStreamConstants.END_DOCUMENT) {
        LOG.info(StaxUtils.eventDescription(reader));
    }
    reader.require(XMLStreamConstants.END_DOCUMENT, null, null);
    reader.close();
}

您的XML可能格式不好,我想真正的XML文档不是您在文章中所放的,因为这看起来没问题。@biziclop我已经用那个确切的XML进行了测试。它给出的错误是有效的。。。读者抛出它是因为它找到了第三个元素的结束标记,并认为我正在尝试结束第一个元素。我想知道的是,有没有办法解决这个问题?它绝对不会这样做。您的XML或代码(您的问题中没有包含)中可能有错误。@biziclop请参阅编辑以获取代码。谢谢你的意见。谢谢,但这不起作用。如果尝试获取元素的文本,则会出现以下错误:
Message:elementGetText()函数只需要文本元素,但遇到START\u元素。
代码的工作方式与演示的相同:)如果需要元素中的文本,则必须调用
reader\getText()
(或相关函数)当光标位于
字符
事件时(参见示例输出,显示所有数据!)。如果您发布的代码很麻烦,我们可以更好地帮助您。让您的代码正常工作。张贴了我的麻烦代码。感谢您的输入。额外提示:1)在
开关
语句中始终使用
默认
子句。如果使用
XMLStreamReader
,您应该使用堆栈或数据块来跟踪所访问的元素。。。发送XML的函数正在剥离最后的元素标记。谢谢你的帮助。
@Test
public void testSO_31815379() throws XMLStreamException, UnsupportedEncodingException {
    final String xml = 
        "<root>\n" +
        "    <element>\n" +
        "        <attribute>level0</attribute>\n" +
        "        <element>\n" +
        "            <attribute>level1</attribute>\n" +
        "            <element>\n" +
        "                <attribute>level2</attribute>\n" +
        "            </element>\n" +
        "        </element>\n" +
        "    </element>\n" +
        "</root>";

    final XMLStreamReader reader = XMLInputFactory.newInstance()
        .createXMLStreamReader(new ByteArrayInputStream(xml.getBytes("UTF-8")));
    LOG.info("Using XMLStreamReader implementation: %s", reader.getClass().getName());

    reader.require(XMLStreamConstants.START_DOCUMENT, null, null);
    int event;
    while ((event = reader.next()) != XMLStreamConstants.END_DOCUMENT) {
        LOG.info(StaxUtils.eventDescription(reader));
    }
    reader.require(XMLStreamConstants.END_DOCUMENT, null, null);
    reader.close();
}
Using XMLStreamReader implementation: com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl
START_ELEMENT<{}root>
CHARACTERS=<whitespace>
START_ELEMENT<{}element>
CHARACTERS=<whitespace>
START_ELEMENT<{}attribute>
CHARACTERS='level0'
END_ELEMENT<attribute>
CHARACTERS=<whitespace>
START_ELEMENT<{}element>
CHARACTERS=<whitespace>
START_ELEMENT<{}attribute>
CHARACTERS='level1'
END_ELEMENT<attribute>
CHARACTERS=<whitespace>
START_ELEMENT<{}element>
CHARACTERS=<whitespace>
START_ELEMENT<{}attribute>
CHARACTERS='level2'
END_ELEMENT<attribute>
CHARACTERS=<whitespace>
END_ELEMENT<element>
CHARACTERS=<whitespace>
END_ELEMENT<element>
CHARACTERS=<whitespace>
END_ELEMENT<element>
CHARACTERS=<whitespace>
END_ELEMENT<root>