расширяется до

аюсь написать XPath, который будет выбирать определенные узлы, которые содержат определенное слово. В данном случае слово «Локвуд». Правильный ответ 3. Оба эти пути дают мне 3.

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>
 Dimitre Novatchev12 янв. 2011 г., 22:51
Хороший вопрос, +1. Смотрите мой ответ для объяснения, полного и простого решения и для полезного правила для запоминания. :)

Ответы на вопрос(1)

Но когда я пытаюсь вывести текст каждого конкретного узла

//*[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', и который является третьим таким дочерним элементом его родителя. Ни один узлы не выбраны! ..)))>. (EN))

Решение:

Использование:

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

Каждый из них выбирает именно N-й элемент (N = {1,2,3}), выбранный//*[contains(./*,'Lockwood')]соответственно:BusinesLetter, Recipient а такжеBody.

Помните:

[] оператор имеет более высокий приоритет (приоритет), чем// Сокращенное название.

 user35781213 янв. 2011 г., 00:30
+1 Хороший ответ. Формально изw3.org/TR/xpath/#NT-Predicate : Предикат фильтрует набор узлов относительно оси, чтобы создать новый набор узлов , И это//*[1] расширяется до/descendant-or-self::node()/child::*[1]

Ваш ответ на вопрос