2012-05-24 3 views
1

У меня есть файл XML, как это:XPath не работает

<?xml version="1.0" encoding="UTF-8"?> 
<!ELEMENT family (person)+> 
<!ELEMENT person (name) > 
<!ATTLIST person idnum ID #REQUIRED 
gender (male | female) #REQUIRED 
father IDREF #IMPLIED 
mother IDREF #IMPLIED 
children IDREFS #IMPLIED > 
<!ELEMENT name (#PCDATA)> 

<?xml version="1.0"?> 
<!DOCTYPE family SYSTEM "family.dtd"> 
<family> 
<person idnum = "T11" gender = "male" children ="T13 T14 T15"><name>11</name></person> 
<person idnum = "T12" gender = "female" children ="T13 T14 T15"><name>12</name></person> 
<person idnum = "T13" gender = "male" father="T11" mother="T12"><name>13</name></person> 
<person idnum = "T14" gender = "male" father="T11" mother="T12"><name>14</name></person> 
<person idnum = "T15" gender = "female" father="T11" mother="T12" children="T33"><name>15</name></person> 
<person idnum = "T21" gender = "male" children="T23"><name>21</name></person> 
<person idnum = "T22" gender = "female" children="T23"><name>22</name></person> 
<person idnum = "T23" gender = "male" father="T21" mother="T22" children="T33"><name>23</name></person> 
<person idnum = "T33" gender = "female" father="T23" mother="T15"><name>33</name></person> 
</family> 

Я хочу, чтобы проверить запросы:

  1. Все люди без детей (как male & female)

  2. Все люди, не имеющие детей мужского пола (то есть SONS)

Я пробовал:

  1. /family/person[count(children)==0]

  2. /family/person[count(children)==0 and children!=male]

Но это не работает.

Не могли бы вы объяснить? Благодарю .

ответ

2

Равного оператор в XPath является «=» , а не «==».

Написание детей! = Мужчина был предположительно желаемым за действительное, вы на самом деле не представляли, что это сработает, надеюсь.

Предположительно, кто-то без детей может быть представлен либо отсутствием атрибута @children, либо наличием атрибута, но пустым. Вы можете охватить оба случая для вашего первого запроса путем тестирования /family/person[normalize-space(@children)='']

Второй запрос сложнее, поскольку он включает соединение. XPath 1.0 не может обрабатывать каждый запрос соединения; XPath 2.0 может. Вы не говорите, что используете. Еще одно осложнение заключается в том, что функция id() может быть немного беспорядочной: конвейер обработки не всегда сохраняет информацию о том, какие атрибуты являются идентификаторами. Но при условии, что id() работает в вашей среде, вы можете выполнить второй запрос (в XPath 1.0 или 2.0) как

/family/person[not(id(@children)[@gender='male'])] 
1

Эти неправильные xpath. Вы пытаетесь найти элементы-дети, но они являются атрибутами.

Это должно быть что-то вроде этого:

//person[not(@children)] 
+1

Это неправильно. '@ children' полностью отсутствует, а не' '' '. – Tomalak

+0

О, ты прав. Я отредактирую свой ответ. –

1
  1. Вы можете использовать "лицо", как XML-тег, но тег-атрибут. Поэтому вам лучше использовать @children.
  2. Использование COUNT (@children) не будет работать, потому что есть только один атрибут с именем дети
  3. Вы не можете стыки и сосчитать строки из атрибутов значений
+0

3.) Ну, вы можете подсчитать количество токенов в строке. 'string-length (normalize-space (@children)) - string-length (translate (normalize-space (@children), '', ''))'. Не то чтобы это помогло в ситуации, но в любом случае. – Tomalak