2013-04-09 2 views
14

Ho un qualcosa di input XML su questa linea:Come dire usando XPath se un elemento è presente e non vuoto?

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

mio intervento su una XML dipende da se <PolNumber> (suo un elemento facoltativo nello schema) ha un valore oppure no. Sto usando Mule 3.3 xpath valutatore per fare questo e la mia espressione XPath sembra questo:

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

Questo funziona bene fino a quando <PolNumber> elemento è presente o è <PolNumber/> elemento vuoto. Ma se <PolNumber> è assente, l'espressione sopra genera eccezione.

Ho provato a utilizzare la funzione XPath boolean ma restituisce true per <PolNumber/>. C'è un modo migliore per verificare se un elemento è presente e non vuoto?

EDIT:

Questa è la configurazione di responsabile dello spazio dei nomi nel mio config mulo

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

risposta

21

Uso:

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

questo produce true() se //acord:Holding/acord:Policy/acord:PolNumber ha un primo figlio di testo-nodo e false() altrimenti.

Do atto: Questo è più efficiente rispetto a contare tutti i bambini text-nodo solo per confrontare il conteggio con 0.

+0

Sono d'accordo che è meglio di contare tutti i bambini con nodi di testo, ma anche questa soluzione non è a prova di tutto. questo xpath restituirà true per ''. Non so come mostrare una nuova riga nel commento ma il mio intento era quello di avere un nuovo carattere di linea tra '' e '' –

+2

@Learner, Questo è semplice: 'booleano (// acord: Holding/acord : Policy/acord: PolNumber/text() [normalize-space()] [1]) ' –

+1

Grazie Dimitre. Non ho esposizione con xpath, tutto ciò è molto utile per me. –

1

Cosa succede ad usare count per ottenere il numero di nodi di testo:

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

Grazie per la risposta. 'Nessuna funzione del genere {http://www.mulesoft.org/schema/mule/core}:count (org.jaxen.UnresolvableException) org.jaxen.SimpleFunctionContext: l'eccezione 127 'viene generata per la funzione count. –

+0

Ho modificato l'espressione sopra in '' e ciò ha funzionato, tuttavia, per '' il conteggio è diverso da zero come la funzione 'boolean' –

+0

Strano devi prefisso con' fn'. Modifica la tua domanda e mostra come è configurato il tuo gestore di spazi dei nomi per favore –

8

È possibile utilizzare boolean(...) per verificare se è vuoto, ma assicurati di cercare all'interno di l'elemento.

boolean(//PolNumber/node()) 

Questo funziona anche se sono presenti altri nodi. Se si desidera limitare i nodi di testo, sostituire node() per text(). Si potrebbe voler usare //text() invece, quindi la query produrrà anche true per i nodi di testo all'interno di altri elementi figlio di <PolNumber/>.

2

Come su expression="#[?xpath('//acord:Holding/acord:Policy/acord:PolNumber').text != empty]"? Questo dovrebbe funzionare in tutte le situazioni

0

Forse sono un po 'in ritardo qui, ma le risposte sono un po' confuse. Questo restituirà sempre false quando il testo è vuoto o con spazi ma senza caratteri.

boolean//Holding/Policy/PolNumber/child/text()[normalize-space()]