2011-01-12 5 views
5

J'essaye d'écrire un XPath qui sélectionnera certains nœuds contenant un mot spécifique. Dans ce cas, le mot est «Lockwood». La réponse correcte est 3. Ces deux chemins me donnent 3.XSLT Sélectionner tous les nœuds contenant une sous-chaîne spécifique

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

Mais lorsque je tente de sortir le texte de chaque noeud spécifique

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

1 nœud finit contenant le texte et les noeuds 2 et 3 sont vides. Est-ce que quelqu'un peut me dire s'il vous plaît ce qui se passe ou ce que je fais mal.

Merci.

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

Bonne question, +1. Voir ma réponse pour l'explication, la solution complète et facile et pour une règle utile à retenir. :) –

Répondre

10

Mais lorsque je tente de sortir le texte de chaque noeud spécifique

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

nœud 1 finit contenant tout le texte et les nœuds 2 et 3 sont vides

Ceci est une FAQ.

//SomeExpression[1] 

n'est pas l'équivalent de

(//someExpression)[1] 

Les anciens noeuds //SomeExpression tous les sélectionne qui sont le premier enfant de leur parent.

Cette dernière sélectionne la première (dans l'ordre des documents) de tous les noeuds //SomeExpression dans l'ensemble du document.

Comment cela s'applique-t-il à votre problème?

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

Ceci sélectionne tous les éléments qui ont au moins un enfant dont la chaîne contient la valeur «Lockwood et que sont le premier de ces enfants de leur parent. Les trois éléments ayant un nœud de texte contenant la chaîne 'Lockwood' sont les premiers de ces parents, ce qui fait que trois éléments sont sélectionnés.

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

Il n'y a aucun élément qui a un enfant avec une valeur de chaîne contenant la chaîne « Lockwood » et est le deuxième enfant de son parent. Aucun noeud n'est sélectionné.

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

Il n'y a aucun élément qui a un enfant avec une valeur de chaîne contenant la chaîne « Lockwood » et est le troisième enfant de son parent. Aucun noeud n'est sélectionné.

Solution:

Utilisation:

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

Chacun de ces sélectionne exactement l'élément Nième (N = {1,2,3}) sélectionnée par //*[contains(./*,'Lockwood')], de manière correspondante: BusinesLetter, Recipient et Body.

Rappelez-vous:

L'opérateur [] a la priorité plus élevée (priorité) que l'abréviation //.

+1

+1 Bonne réponse. Formellement à partir de http://www.w3.org/TR/xpath/#NT-Predicate: * Un prédicat filtre un ensemble de nœuds par rapport à un axe pour produire un nouvel ensemble de nœuds *. Et ce '// * [1]' est développé en '/ descendant-or-self :: node()/child :: * [1]' –

Questions connexes