2011-01-12 16 views
5

Sto provando a scrivere un XPath che selezionerà determinati nodi che contengono una parola specifica. In questo caso la parola è "Lockwood". La risposta corretta è 3. Entrambi questi percorsi mi dia 3.XSLT Seleziona tutti i nodi contenenti una sottostringa specifica

count(//*[contains(./*,'Lockwood')]) 
count(BusinessLetter/*[contains(../*,'Lockwood')]) 

Ma quando provo per l'uscita del testo di ciascun nodo specifico

//*[contains(./*,'Lockwood')][1] 
//*[contains(./*,'Lockwood')][2] 
//*[contains(./*,'Lockwood')][3] 

Nodo 1 finisce contenente tutto il testo e nodi 2 e 3 sono vuoti.

Qualcuno può dirmi cosa sta succedendo o cosa sto facendo male.

Grazie.

<?xml version="1.0" encoding="UTF-8"?> 
<?xml-stylesheet type="text/xsl" href="XPathFunctions.xsl"?> 
<BusinessLetter> 
<Head> 
    <SendDate>November 29, 2005</SendDate> 
    <Recipient> 
    <Name Title="Mr."> 
    <FirstName>Joshua</FirstName> 
    <LastName>Lockwood</LastName> 
    </Name> 
    <Company>Lockwood &amp; Lockwood</Company> 
    <Address> 
    <Street>291 Broadway Ave.</Street> 
    <City>New York</City> 
    <State>NY</State> 
    <Zip>10007</Zip> 
    <Country>United States</Country> 
    </Address> 
    </Recipient> 
</Head> 
<Body> 
    <List> 
    <Heading>Along with this letter, I have enclosed the following items:</Heading> 
    <ListItem>two original, execution copies of the Webucator Master Services Agreement</ListItem> 
    <ListItem>two original, execution copies of the Webucator Premier Support for Developers Services Description between Lockwood &amp; Lockwood and Webucator, Inc.</ListItem> 
    </List> 
    <Para>Please sign and return all four original, execution copies to me at your earliest convenience. Upon receipt of the executed copies, we will immediately return a fully executed, original copy of both agreements to you.</Para> 
    <Para>Please send all four original, execution copies to my attention as follows: 

<Person> 
    <Name> 
    <FirstName>Bill</FirstName> 
    <LastName>Smith</LastName> 
    </Name> 
    <Address> 
    <Company>Webucator, Inc.</Company> 
    <Street>4933 Jamesville Rd.</Street> 
    <City>Jamesville</City> 
    <State>NY</State> 
    <Zip>13078</Zip> 
    <Country>USA</Country> 
    </Address> 
    </Person> 
    </Para> 
    <Para>If you have any questions, feel free to call me at <Phone>800-555-1000 x123</Phone> or e-mail me at <Email>[email protected]</Email>.</Para> 
</Body> 
<Foot> 
    <Closing> 
    <Name> 
    <FirstName>Bill</FirstName> 
    <LastName>Smith</LastName> 
    </Name> 
    <JobTitle>VP of Operations</JobTitle> 
    </Closing> 
</Foot> 
</BusinessLetter> 
+0

Buona domanda, +1. Vedi la mia risposta per una spiegazione, una soluzione completa e facile e per un'utile regola da ricordare. :) –

risposta

10

Ma quando si tenta di emissione del testo di ciascun nodo specifico

//*[contains(./*,'Lockwood')][1] 
//*[contains(./*,'Lockwood')][2] 
//*[contains(./*,'Lockwood')][3] 

Nodo 1 finisce contenente tutto il testo e nodi 2 e 3 sono vuote

Questa è una FAQ.

//SomeExpression[1] 

non è l'equivalente di

(//someExpression)[1] 

Gli ex seleziona tutti //SomeExpression nodi che sono il primo figlio del loro genitore.

Quest'ultimo seleziona il primo (nell'ordine del documento) di tutti i nodi //SomeExpression nell'intero documento.

In che modo si applica al problema?

//*[contains(./*,'Lockwood')][1] 

Questo seleziona tutti gli elementi che hanno almeno un figlio il cui valore stringa contiene 'Lockwood' e che sono il primo di questi bambini dei loro genitori. Tutti e tre gli elementi che hanno un nodo di testo contenente la stringa "Lockwood" sono i primi figli dei loro genitori, quindi il risultato è che sono selezionati tre elementi.

//*[contains(./*,'Lockwood')][2] 

Non v'è alcun elemento che ha un figlio con un valore stringa che contiene la stringa 'Lockwood' ed è la seconda come figlio del suo genitore. Nessun nodo selezionato.

//*[contains(./*,'Lockwood')][3] 

Non v'è alcun elemento che ha un figlio con un valore stringa che contiene la stringa 'Lockwood' ed è il terzo di questi bambini del suo genitore. Nessun nodo selezionato.

Soluzione:

Uso:

(//*[contains(./*,'Lockwood')])[1] 
(//*[contains(./*,'Lockwood')])[2] 
(//*[contains(./*,'Lockwood')])[3] 

Ciascuno di questi seleziona esattamente l'elemento Nth (N = {1,2,3}) selezionato dal //*[contains(./*,'Lockwood')] corrispondentemente: BusinesLetter, Recipient e Body.

Ricorda:

Il [] operatore ha una maggiore priorità (precedenza) rispetto al // sigla.

+1

+1 buona risposta. Formalmente da http://www.w3.org/TR/xpath/#NT-Predicate: * Un predicato filtra un set di nodi rispetto a un asse per produrre un nuovo set di nodi *. E questo '// * [1]' viene espanso in '/ descendant-or-self :: node()/child :: * [1]' –

Problemi correlati