2013-06-24 2 views
1

Я уже здесь часами. Кажется, я не прав.Нечеткое совпадение в XPath с использованием функции count()

У меня есть этот пример XML-файл:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<!-- Edited by XMLSpy® --> 
<bookstore> 

<book category="COOKING"> 
    <title lang="en">Everyday Italian</title> 
    <author>Giada De Laurentiis</author> 
    <year>2005</year> 
    <price>30.00</price> 
</book> 

<book category="CHILDREN"> 
    <title lang="en">Harry Potter</title> 
    <author>J K. Rowling</author> 
    <year>2005</year> 
    <price>29.99</price> 
</book> 

<book category="WEB"> 
    <title lang="en">XQuery Kick Start</title> 
    <author>James McGovern</author> 
    <author>Per Bothner</author> 
    <author>Kurt Cagle</author> 
    <author>James Linn</author> 
    <author>Vaidyanathan Nagarajan</author> 
    <year>2003</year> 
    <price>49.99</price> 
</book> 

<book category="WEB"> 
    <title lang="en">Learning XML</title> 
    <author>Erik T. Ray</author> 
    <year>2003</year> 
    <price>39.95</price> 
</book> 

</bookstore> 

Я пытаюсь использовать функцию подсчета() в XPath, чтобы вернуться, сколько раз появляется значение в файле (возвращает количество элементов, содержащих это значение).

Я в настоящее время используют:

count(//*[contains(author, 'J K.')]) 

И это возвращение '1', который является правильным. Теперь, допустим, я не знаю, в каком элементе или атрибуте значение, которое я ищу, находится. Если я пытаюсь использовать:

count(//*[contains(/*, 'J K.')]) 

Это возвращает «25», что является подсчетом всех узлов в файле. Я думал, что первый параметр в функции contains в предикате указывает, где искать значение. Однако в этом случае представляется значение возвращаемого значения. Я немного запутался. Я также попытался это:

query = "count(//*[contains(/*, 'J K.')]/book/..)"; 

Это также возвращает правильное значение, но опять же, вы должны знать уровень, при котором величина находится. Если у вас более сложный файл с несколькими уровнями для разных узлов, и вы все еще хотите искать весь файл, как вы это делаете?

+1

Ваш пример ввода не соответствует указанным вами значениям. Обязательно включите все соответствующие XML или сопоставьте свой вопрос с небольшим, но достаточно большим фрагментом XML (еще лучше). Например, это должно включать иглу более одного раза (все запросы, требующие «J K.», будут давать 1 для этого ввода). –

ответ

2

Это то, что вы не используете текущий контекст внутри предиката, но начинаете с корня снова.


Учитывая вы хотите запросить количество книг, содержащих «J К.», применяется содержит в контексте всех книг:

count(//book[contains(., 'J K.')]) 

Если вы хотите, чтобы подсчитать количество вхождений тегов, содержащих текстовый узел «J K.», это легко, также:

count(//*[contains(text(), 'J K.')]) 

Подсчет количества текстовых узлов, содержащих иглу будет легко, тоже:

count(//text()[contains(., 'J K.')]) 

Подсчитать количество вхождений этой иглы в XPath 1.0 невозможно. В XPath 2.0, вы должны разделить на вхождений иглы и возвращает количество вхождений минус 1.

count(tokenize(/, 'J K\.'))-1 

Помните fn:tokenize() использует регулярные выражения, поэтому точка должна быть экранированы.

+0

Отлично, это именно то, что я искал. Спасибо. Я закончил: count (// text() [содержит (., 'J K.')]) – rocklandcitizen