在dom4j中使用xPath时使用text()函数

时间:2012-03-28 19:38:22

标签: xpath dom4j

我继承了一个使用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字符串。

1 个答案:

答案 0 :(得分:0)

从您的摘要中,GRD_ERRORSGRD_ERRORS_TMPWRK_REGISTRATIONWRK_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']]