0

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

代码尝试使用 xPath 中提供的 PAGE_ID 和 TRANS_DETAIL_ID 获取页面的 GRD_ERROR 节点。

即使请求的节点在正在搜索的 xml 中,我也看到此 selectSingleNode 请求的间歇性(~1-2%)失败(返回的节点为空)。

我知道在 xPath 中使用 text()= 存在一些问题,并且想知道是否有更好的方法来格式化此类搜索的 xPath 字符串。

4

1 回答 1

0

从您的片段中,关于GRD_ERRORSvs.GRD_ERRORS_TMPWRK_REGISTRATIONvs.存在问题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具有这些条件的子元素的元素,然后使用 this 获取小部件@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']]
于 2012-03-29T17:26:39.610 回答