2013-04-09 11 views
14

Mam coś XML wejście na tej linii:Jak powiedzieć, używając XPath, jeśli element jest obecny i nie jest pusty?

<Holding id="12"> 
    <Policy> 
     <HoldingForm tc="1">Individual</HoldingForm> 
     <PolNumber>848433</PolNumber> 
     <LineOfBusiness tc="1">Life</LineOfBusiness> 
     <CarrierCode>67644</CarrierCode> 
    </Policy> 
</Holding> 

Moja manipulacja na tym XML zależy czy <PolNumber> (jego opcjonalnym elementem schematu) ma wartość, czy nie. Używam Mule 3.3 xpath oceniającego to zrobić i mój wyrażenie XPath wygląda następująco:

<expression-filter expression="#[xpath('//acord:Holding/acord:Policy/acord:PolNumber').text != empty]"/> 

Działa to dobrze, tak długo, jak <PolNumber> elementem jest obecna lub <PolNumber/> jest pusty element. Ale jeśli nie ma wartości <PolNumber>, powyższe wyrażenie zgłasza wyjątek.

Próbowałem użyć funkcji XPath boolean, ale zwraca true dla <PolNumber/>. Czy istnieje lepszy sposób sprawdzenia, czy element jest obecny i czy nie jest pusty?

EDIT:

Jest to konfiguracja menedżera przestrzeni nazw w moim mule config

<xm:namespace-manager includeConfigNamespaces="true"> 
    <xm:namespace prefix="acord" uri="http://ACORD.org/Standards/Life/2" /> 
    <xm:namespace prefix="soap" uri="http://schemas.xmlsoap.org/soap/encoding/" /> 
</xm:namespace-manager> 

Odpowiedz

21

Zastosowanie:

boolean(//acord:Holding/acord:Policy/acord:PolNumber/text()[1]) 

ten produkuje true() jeśli //acord:Holding/acord:Policy/acord:PolNumber ma pierwszy tekst węzłów dziecko i false() inaczej.

Należy pamiętać: To jest bardziej wydajne niż liczenie wszystkich dzieci text-węzłów tylko porównać liczbę z 0.

+0

Zgadzam się, że to jest lepsze niż zliczanie wszystkich dzieci z węzłem tekstowym, ale nawet to rozwiązanie nie jest pełne. ta ścieżka będzie zwracana true dla ' '. Nie wiem, jak wyświetlić komentarz w komentarzu, ale moim zamiarem było uzyskanie nowej linii między '' i '' –

+2

@Learner, To jest proste: 'boolean (// acord: Holding/acord : Policy/acord: PolNumber/text() [normalize-space()] [1]) ' –

+1

Dzięki Dimitre. Nie mam ekspozycji z xpath, wszystko to jest dla mnie bardzo pomocne. –

1

Co na temat korzystania count aby uzyskać liczbę węzłów tekstowych:

<expression-filter 
    expression="#[xpath('count(//Holding/Policy/PolNumber/child::text())') != 0]"/> 
+0

Dziękuję za odpowiedź. 'No Such Function {http://www.mulesoft.org/schema/mule/core}:count (org.jaxen.UnresolvableException) org.jaxen.SimpleFunctionContext: Wyjątek 127' jest zgłaszany do funkcji liczenia. –

+0

Zmieniłem powyższe wyrażenie na '" i to działało jednak dla '' count jest niezerowe, tak jak funkcja 'boolean' –

+0

Dziwne, że musisz poprzedzić' fn'. Edytuj swoje pytanie i pokaż, w jaki sposób skonfigurowany jest twój menedżer przestrzeni nazw. –

8

Można użyć boolean(...) dla sprawdzenia, czy jest pusty, ale upewnij się, że zajrzyj do wnętrza elementu.

boolean(//PolNumber/node()) 

Działa to również w przypadku innych węzłów. Jeśli chcesz ograniczyć węzły tekstowe, zamień node() przez text(). Zamiast tego można użyć wartości //text(), a następnie zapytanie będzie miało wartość true dla węzłów tekstowych w innych elementach potomnych z <PolNumber/>.

2

Jak o expression="#[?xpath('//acord:Holding/acord:Policy/acord:PolNumber').text != empty]"? Powinno to zadziałać we wszystkich sytuacjach.

0

Może trochę się spóźniłem, ale odpowiedzi są nieco mylące. Ten zawsze zwraca wartość false, gdy tekst jest pusty lub zawiera spacje, ale nie znaki.

boolean//Holding/Policy/PolNumber/child/text()[normalize-space()] 
Powiązane problemy