2012-03-28 52 views
0

使用XPath時,我繼承了使用dom4j中和XPath來解析XML應用程序中使用的文字()函數:在dom4j的

的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字符串的格式。

+0

問題可能是由於樹中存在碎片(相鄰)文本節點。這不應該發生,但它確實:http://jira.codehaus.org/browse/JAXEN-67 – 2012-03-28 22:20:31

+0

是的。你可以像'follow-sibling ::'軸那樣使用一些XPath魔術,或者某種選擇多個節點並對它們進行處理,但是這個查詢並不壞,應該可以工作,並且在不使用'text() 。我認爲你最好的選擇是更新到_dom4j v2.0.0 alpha 2_並希望問題會消失在那裏。 – 2012-03-28 23:27:04

+0

感謝您的意見。我意識到與text()相鄰的文本節點問題,因此我們搜索的節點中的文本沒有空格。我們正在使用dom4j.1.6.1。此外,失敗率大約爲千分之一,但仍然每天導致2或3次失敗。在發生故障時,我們打印正在分析的xml和用於日誌的xPath。沒有共同點 - 失敗代表獨特的xml和xPath組合。我會嘗試使用新的dom4j v2.0.0。版本和報告我們的調查結果。 – jlawless 2012-04-11 20:30:51

回答

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']]