XSLT选择包含特定子字符串的所有节点

问题描述:

我正在尝试编写一个XPath,它将选择包含特定单词的某些节点。 在这种情况下,单词是“Lockwood”。正确的答案是3,这两条路径给我3XSLT选择包含特定子字符串的所有节点

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

但是,当我尝试输出每一个特定节点的文本

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

节点1结束了包含所有文字和节点2和3是空白的。

有人可以告诉我发生了什么事或者我做错了什么。

感谢。

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

好问题,+1。请参阅我的回答以获得解释,完整和简单的解决方案,并记住一条有用的规则。 :) – 2011-01-12 21:51:20

但是当我尝试以输出 文本中的每个特定节点

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

节点1结束了包含所有文本 和节点2和3是空白

这是一个常见问题。

//SomeExpression[1] 

是不是等同于

(//someExpression)[1] 

前者选择所有//SomeExpression节点是他们的父母的第一个孩子。

后者选择整个文档中所有//SomeExpression节点的第一个(按文档顺序)。

这是如何适用于您的问题?

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

这将选择至少有一个孩子,他的字符串值包含“洛克伍德”那是他们的父母的第一个孩子等所有元素。所有具有包含字符串“Lockwood”的文本节点的三个元素是其父母的第一个这样的孩子,因此结果是选择了三个元素。

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

没有元素具有包含字符串'Lockwood'的字符串值的子元素,并且是其父元素的第二个这样的子元素。没有选择节点。

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

没有元素具有包含字符串'Lockwood'的字符串值的子元素,并且是其父元素的第三个这样的子元素。没有选择节点。

使用:

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

每个选择准确的第N个元素的(N = {1,2,3})由//*[contains(./*,'Lockwood')],相应地选择:BusinesLetterRecipientBody

记住

[]操作符比//缩写更高的优先级(优先级)。

+1

+1很好的答案。 Formaly from http://www.w3.org/TR/xpath/#NT-Predicate:*谓词过滤一个节点集相对于一个轴产生一个新的节点集*。这个`// * [1]`被扩展到`/ descendant-or-self :: node()/ child :: * [1]` – 2011-01-12 23:30:49