2012-03-28 4 views
0

Verwendung Ich habe eine Anwendung geerbt, die unter Verwendung von XML dom4j und XPath parst:Verwendung von text() Funktion, wenn xPath in dom4j

der XML-geparst wird, ist ähnlich wie die folgenden:

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

Einzelne Nodes mit dem folgenden durchsucht werden:

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); 

wo xmlToParse ist ein String von XML ähnlich dem Auszug oben vorgesehen.

Der Code versucht, den GRD_ERROR-Knoten für die Seite mit der PAGE_ID und der TRANS_DETAIL_ID im xPath zu erhalten.

Ich sehe einen intermittierenden (~ 1-2%) Fehler (der zurückgegebene Knoten ist null) dieser selectSingleNode-Anforderung, obwohl der angefragte Knoten in dem zu durchsuchenden XML enthalten ist.

Ich weiß, dass einige Fehler mit der Verwendung von text() = in xPath verknüpft sind und ich mich gefragt habe, ob es eine bessere Möglichkeit gibt, die xPath-Zeichenfolge für diese Art der Suche zu formatieren.

+0

Es ist möglich, dass das Problem auf fragmentierte (benachbarte) Textknoten im Baum zurückzuführen ist. Das soll nicht passieren, aber es tut: http://jira.codehaus.org/browse/JAXEN-67 –

+0

Yeah. Sie könnten einige XPath-Zauber wie "following-sibling ::" -Achsen oder irgendeine Art von Auswahl mehrerer Knoten verwenden und daran arbeiten, aber diese Abfrage ist nicht schlecht, sollte funktionieren und kann nicht ohne die Verwendung von 'text()' ersetzt werden . Ich denke, dein bester Schuss ist das Aktualisieren auf _dom4j v2.0.0 alpha 2_ und hoffe, dass das Problem dort verschwunden wäre. –

+0

Danke für die Eingabe. Ich war mir des angrenzenden Textknotenproblems mit text() bewusst, so dass der Text in den Knoten, nach denen wir suchen, keine Leerzeichen enthält. Wir verwenden dom4j.1.6.1. Zusätzlich ist die Fehlerrate ungefähr eins zu tausend, aber es ergibt immer noch 2 oder 3 pro Tag. Bei einem Fehler drucken wir die zu analysierende XML und den verwendeten xPath in ein Protokoll. Es gibt keine Gemeinsamkeit - die Fehler stellen eindeutige xml- und xPath-Kombinationen dar. Ich werde versuchen, das neue dom4j v2.0.0 zu verwenden. Version und berichten unsere Ergebnisse. – jlawless

Antwort

0

Von Ihren Snippets gibt es ein Problem bezüglich GRD_ERRORS vs. GRD_ERRORS_TMP und WRK_REGISTRATION vs. WRK_DNA_REGISTRATION.

dass Ignorieren, würde ich

//cache/content/transaction/page 
    /widget[@name='PAGE_ID'][text()='WRK_DNA_REGISTRATION'] 
    /../widget[@name='TRANS_DETAIL_ID'][text()='77147'] 
    /../widget[@name='GRD_ERRORS_TEMP'] 

als

//cache/content/transaction/page 
    [widget[@name='PAGE_ID'][text()='WRK_REGISTRATION']] 
    [widget[@name='TRANS_DETAIL_ID'][text()='77147']] 
    /widget[@name='GRD_ERRORS'] 

einfach zu umschreiben vorschlagen, weil es den Code macht, in meinen Augen, leichter zu lesen, und zum Ausdruck bringt, was Sie scheinen mehr zu bedeuten klar: "Das page Element, das Kinder mit diesen Bedingungen hat, und nehmen Sie dann das Widget mit dieser @name." Oder, wenn das näher ist, wie Sie darüber denken,

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