2010-11-17 2 views
2

Я уверен, что это должно быть проще, чем я это делаю, но я пытаюсь получить следующий ответ от моего источника. Пожалуйста, может кто-нибудь помочь мне с xpath?XPath найти атрибуты с определенными значениями

Я пытаюсь выбрать элементы линии со значениями «extract». В реальном мире я читаю текстовый файл и использую xml и хочу выделить строки, которые читают извлечение.

Источник

<line> 
<line number="1">blah</line> 
<line number="2">extract</line> 
<line number="3">blah</line> 
<line number="4">extract</line> 
</line> 

Необходимое Ответ:

<line> 
<line number="2">extract</line> 
<line number="4">extract</line> 
</line> 

или даже просто

экстракт

экстракт

будет хорошо.

Большое спасибо,

+0

Хороший вопрос, +1. См. Мой ответ на два коротких решения. :) –

+0

Да, это просто. Но для этого требуется некоторое разъяснение. Если вы хотите преобразование (результат XML), вам нужен XSLT. Если вы хотите ** выбрать ** текстовые узлы **, содержащие ** строку «extract», то это возможно только с XPath. Если вы хотите выбрать текстовые узлы с строковым значением «extract», это выглядит странно как запрос ... – 2010-11-17 21:56:55

ответ

0
//line[contains(text(), 'extract')] 

EDIT: Это работает для XPath 1.0, и это, очевидно, ищет строки (а не требовать равенства).

+0

Это не сработает, потому что в этом случае '// line' не равно'/line/line', а верхний тег 'line' содержит несколько строк, поэтому' contains' терпит неудачу. И 'contains()' может вызывать при неправильных значениях ex 'contains (text(), 'a')' даст вам все элементы. –

1

Это (использование =, если вы используете XPath 1.0):

/line/line[text() eq 'extract']/text() 

даст вам: (See evaluation)

extract 
extract 

Причина, почему //line не является хорошей идеей, является то, что вы используете line теги для 2 вещей (ваш верхний тег line и ваши дети line) - вы не должны этого делать: - /. Если вы хотите, чтобы элементы вместо текста, вы можете написать:

/line/line[text() eq 'extract'] 

И наконец, это даст вам количество (? Кажется, это то, что вам действительно нужно)

count(/line/line[text() eq 'extract']) 
+0

@lasseespeholt: 'eq' является оператором XPath 2.0. – 2010-11-17 21:44:30

+0

@lasseespeholt: Кроме того, я согласен с вами в рекомендации о том, чтобы не использовать начальный оператор '//', удаленное решение '// строка [содержит (текст(), 'extract')]' ** будет работать **, потому что Корневой элемент 'line' не имеет текстового узла ** child **, содержащего строку« extract ». В другом случае это будет, если вы используете строковое значение (с текущим '.' Неявным литьем или с функцией 'string()'). – 2010-11-17 21:50:06

+0

Я не знаю, правильны ли вы, но XQSharp (попробуйте «См. Оценку») говорит, что он не работает, но он может быть реализован неправильно. Это потому, что 'text()' не является одной строкой. Кроме того, 'contains' может вызывать при неправильных значениях ex' contains (.., 'a') 'будет true с' blah'. –

0

Так как ваш объект упоминает атрибуты (даже если ваш вопрос не подходит). Я предполагаю, что вы хотите найти значение атрибута number для всех соответствующих строк. Если это так:

/line/line[text()='extract']/@number 
1

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

/*/*[.='extract']/text() 

или даже:

//text()[.='extract'] 
Смежные вопросы