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