我继承了一个使用dom4j和xPath解析xml的应用程序:
正在解析的xml类似于以下内容:
<cache>
<content>
<transaction>
<page>
<widget name="PAGE_ID">WRK_REGISTRATION</widget>
<widget name="TRANS_DETAIL_ID">77145</widget>
<widget name="GRD_ERRORS" />
</page>
<page>
<widget name="PAGE_ID">WRK_REGISTRATION</widget>
<widget name="TRANS_DETAIL_ID">77147</widget>
<widget name="GRD_ERRORS" />
</page>
<page>
<widget name="PAGE_ID">WRK_PROCESSING</widget>
<widget name="TRANS_DETAIL_ID">77152</widget>
<widget name="GRD_ERRORS" />
</page>
</transaction>
</content>
</cache>
正在使用以下内容搜索单个节点:
String xPathToGridErrorNode = "//cache/content/transaction/page/widget[@name='PAGE_ID'][text()='WRK_DNA_REGISTRATION']/../widget[@name='TRANS_DETAIL_ID'][text()='77147']/../widget[@name='GRD_ERRORS_TEMP']";
org.dom4j.Element root = null;
SAXReader reader = new SAXReader();
Document document = reader.read(new BufferedInputStream(new ByteArrayInputStream(xmlToParse.getBytes())));
root = document.getRootElement();
Node gridNode = root.selectSingleNode(xPathToGridErrorNode);
其中xmlToParse是xml的String,类似于上面提供的摘录。
代码正在尝试获取具有xPath中提供的PAGE_ID和TRANS_DETAIL_ID的页面的GRD_ERROR节点。
我看到此selectSingleNode请求的间歇性(~1-2%)失败(返回节点为空),即使请求的节点位于正在搜索的xml中。
我知道在xPath中使用text()=有一些问题,并且想知道是否有更好的方法来格式化此类搜索的xPath字符串。
答案 0 :(得分:0)
从您的摘要中,GRD_ERRORS
与GRD_ERRORS_TMP
和WRK_REGISTRATION
与WRK_DNA_REGISTRATION
存在问题。
忽略这一点,我建议重写
//cache/content/transaction/page
/widget[@name='PAGE_ID'][text()='WRK_DNA_REGISTRATION']
/../widget[@name='TRANS_DETAIL_ID'][text()='77147']
/../widget[@name='GRD_ERRORS_TEMP']
作为
//cache/content/transaction/page
[widget[@name='PAGE_ID'][text()='WRK_REGISTRATION']]
[widget[@name='TRANS_DETAIL_ID'][text()='77147']]
/widget[@name='GRD_ERRORS']
只是因为它使我的眼中的代码更容易阅读,并且表达了你似乎更清楚的意思:“具有这些条件的孩子的page
元素,然后用这个带小部件@name
。“或者,如果这更接近你的想法,
//cache/content/transaction/page/widget[@name='GRD_ERRORS']
[preceding-sibling::widget[@name='PAGE_ID'][text()='WRK_REGISTRATION']]
[preceding-sibling::widget[@name='TRANS_DETAIL_ID'][text()='77147']]