Java 解析嵌套在其他XML值中的XML标记
我一直在开发一个特定的XML解析器来解析大量XML 我的问题是,我不知道如何解析嵌套在其他XML值中的XML标记。 我的输入文件看起来像这样Java 解析嵌套在其他XML值中的XML标记,java,xml,xpath,xml-parsing,jaxp,Java,Xml,Xpath,Xml Parsing,Jaxp,我一直在开发一个特定的XML解析器来解析大量XML 我的问题是,我不知道如何解析嵌套在其他XML值中的XML标记。 我的输入文件看起来像这样 <main> <step> <para>Calculate the values from the pool</para> </step> <step> <para>Use these(<internalRef id ="003" xlink:
<main>
<step>
<para>Calculate the values from the pool</para>
</step>
<step>
<para>Use these(<internalRef id ="003" xlink:actuate="onRequest" xlink:show="replace" xlink:href="max003"/>) values finally</para>
</step>
</main>
计算池中的值
最后使用这些()值
我能够使用xpath获取第一步标记的值。
我的问题是如何使用xpath获取第二步的值,或者更确切地说,如何识别值标记中的新标记何时开始
例如,我的第二步xpath返回这个结果-最后使用这些()值
我的目标是获得-最终使用这些(max003)值
max003值必须取自xlink:href
添加-我可以通过编写单独的XPath来获取id、actuate和show的单个值。我的问题是,在获得xlink:href值(即max003)后,我需要将max003值填充在这些之后和值之前的括号内,并通过导线发送以供显示所以我正在寻找一种方法来识别子节点id在何时何地启动?和一种将其放入括号中的机制。尽我所能,我认为您的解析器在查看您的结构时有点像
step
+- para
+-id
然后将“文本”内容包装在一起,以提取id节点
(这纯粹是猜测)
更新
如果我简单地遍历节点树(列出每个子节点),这就是我得到的结果
main
step
para
#text - Calculate the values from the pool
step
para
#text - Use these(
id
#text - ) values finally
这意味着“id”是“para”的子元素,我想你的解析器看起来有点像
step
+- para
+-id
然后将“文本”内容包装在一起,以提取id节点
(这纯粹是猜测)
更新
如果我简单地遍历节点树(列出每个子节点),这就是我得到的结果
main
step
para
#text - Calculate the values from the pool
step
para
#text - Use these(
id
#text - ) values finally
这意味着“id”是“para”的子项仅使用XPath是无法做到这一点的。这里有混合内容XML,这意味着一个元素可能同时包含文本值和子元素。使用XPath一次只能引用其中一个表达式,也不能只解析从多个XPath表达式中获得的内容,因为文本值可能会围绕在示例中所述的子元素周围 我建议您要么使用XSLT转换文档,然后像现在一样使用XPath查询转换后的文档。另一种方法是编写自己的解析器,该解析器能够正确处理嵌套元素 此XSLT可能适用于您(尚未完全测试):
当然,您需要使用XSLT处理器来转换原始文档
解析器可能是这样的(注意,这只是StAX解析器的框架代码):
导入java.io.StringReader;
导入java.util.Iterator;
导入javax.xml.stream.XMLEventReader;
导入javax.xml.stream.XMLInputFactory;
导入javax.xml.stream.XMLStreamException;
导入javax.xml.stream.XMLStreamReader;
导入javax.xml.stream.events.Attribute;
导入javax.xml.stream.events.Characters;
导入javax.xml.stream.events.EndElement;
导入javax.xml.stream.events.StartElement;
导入javax.xml.stream.events.XMLEvent;
公共类ExampleStAXParser{
私有静态最终整数状态_UNDEFINED=1;
私有静态最终int状态_MAIN=2;
私有静态最终int状态_步骤=3;
私有静态最终整数状态_PARA=4;
私有静态最终字符串EL_MAIN=“MAIN”;
私有静态最终字符串EL_STEP=“STEP”;
私有静态最终字符串EL_PARA=“PARA”;
私有静态最终字符串EL_INTERNAL_REF=“internalRef”;
私有静态最终字符串ATT_HREF=“HREF”;
private int state=未定义的状态;
私有字符串;
公共void解析(字符串xmlString)引发XMLStreamException,异常{
XMLEventReader=null;
试一试{
if(xmlString==null | | xmlString.isEmpty()){
抛出新的IllegalArgumentException(“非法初始化(xmlString为null或空)”;
}
StringReader StringReader=新的StringReader(xmlString);
XMLInputFactory inputFact=XMLInputFactory.newInstance();
XMLStreamReader streamReader=inputFact.createXMLStreamReader(stringReader);
reader=inputFact.createXMLEventReader(streamReader);
while(reader.hasNext()){
XMLEvent事件=reader.nextEvent();
if(event.isCharacters()){
人物(事件);
}
if(event.isStartElement()){
startElement(事件);
//句柄属性
迭代器属性=event.asStartElement().getAttributes();
while(attributes.hasNext()){
属性(attributes.next());
}
}
if(event.isEndElement()){
结束(事件);
}
if(event.isStartDocument()){
开始文件(事件);
}
if(event.isEndDocument()){
结束文件(事件);
}
}
}捕获(XMLStreamException ex){
掷骰子;
}最后{
试一试{
if(读卡器!=null){
reader.close();
}
}捕获(XMLStreamException ex){
}
}
}
私有void属性(XMLEvent事件)引发异常{
if(state==state_PARA){
属性attr=(属性)事件;
concat(/*/step[2]/para/text()[1],
/*/step[2]/para/internalRef/@xlink:href,
/*/step[2]/para/text()[2])
<main xmlns:xlink="Undefined namespace">
<step>
<para>Calculate the values from the pool</para>
</step>
<step>
<para>Use these(<internalRef id ="003" xlink:actuate="onRequest" xlink:show="replace" xlink:href="max003"/>) values finally</para>
</step>
</main>
Use these(max003) values finally
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xlink="Undefined namespace">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<xsl:copy-of select=
"concat(/*/step[2]/para/text()[1],
/*/step[2]/para/internalRef/@xlink:href,
/*/step[2]/para/text()[2])
"/>
</xsl:template>
</xsl:stylesheet>
Use these(max003) values finally