#regex #xpath #attributes
#регулярное выражение #xpath #атрибуты
Вопрос:
Я искал и возился в течение нескольких часов, пытаясь взломать это, но у меня все еще возникают проблемы. У меня есть XML-данные ниже:
<game id="2009/05/02/arimlb-milmlb-1" pk="244539">
<team id="109" name="Arizona" home_team="false">
<event number="9" inning="1" description="Felipe Lopez doubles to left fielder Chris Duffy. "/>
<event number="15" inning="1" description="Augie Ojeda flies out to center fielder Mike Cameron. "/>
<event number="23" inning="1" description="Chad Tracy doubles to right fielder Joe Sanchez. "/>
<event number="52" inning="2" description="Mark Reynolds lines out to left fielder Chris Duffy. "/>
<!-- more data here -->
</team>
</game>
Я пытаюсь получить общее количество узлов события, которые содержат текст «удваивается» в значении атрибута description. Это то, что я пытался до сих пор, безрезультатно (irb выдает ошибку):
"/game/team/event/@description[matches(.,' doubles ')]"
Поскольку я просто пытаюсь сопоставить фрагмент значения атрибута description, можно использовать функцию XPath 2.0 ‘matches’, верно? Если да, то что я делаю не так?
Комментарии:
1. Хороший вопрос, 1. Смотрите мой ответ для полного, короткого и простого однострочного решения XPath-expression 🙂
2. Mikecito — Я использую Java 1.6, но я также использую Ruby irb для целей разработки и отладки с такими материалами, как XPath. То есть сначала я пытался отсканировать файл, используя XPath в irb, и как только у меня был XPath, который давал то, что я хотел, я бы перенес его в свой Java-код.
3. Dimitre — Указанный вами XPath в конечном итоге отлично сработал. Я оставлю отдельный комментарий под вашим сообщением.
Ответ №1:
Я пытаюсь получить общее количество узлов события, которые содержат текст «удваивается» в значении атрибута description.
matches()
является стандартной функцией XPath 2.0. Это недоступно в XPath 1.0.
Вы можете использовать:
count(/*/*/event[contains(@description, ' doubles ')])
Чтобы проверить это, вот небольшое преобразование XSLT, которое просто выводит результат вычисления приведенного выше выражения XPath в предоставленном XML-документе:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:value-of select=
"count(/*/*/event[contains(@description, ' doubles ')])"/>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к предоставленному XML-документу:
<game id="2009/05/02/arimlb-milmlb-1" pk="244539">
<team id="109" name="Arizona" home_team="false">
<event number="9" inning="1" description="Felipe Lopez doubles to left fielder Chris Duffy. "/>
<event number="15" inning="1" description="Augie Ojeda flies out to center fielder Mike Cameron. "/>
<event number="23" inning="1" description="Chad Tracy doubles to right fielder Joe Sanchez. "/>
<event number="52" inning="2" description="Mark Reynolds lines out to left fielder Chris Duffy. "/>
<!-- more data here -->
</team>
</game>
получен желаемый, правильный результат:
2
Комментарии:
1. Димитр — Как я упоминал выше, XPath в вашем сообщении отлично сработал. В итоге я сделал это более конкретным следующим образом:
"count(/game/team[@home_team='false']/event[contains(@description, ' doubles ')])"
Большое спасибо за вашу помощь! Я действительно ценю это. И Java 1.6, по-видимому, не поддерживает XPath 2.0.
Ответ №2:
Попробуйте следующие варианты:
/game/team/event[matches(@description, ' doubles ')]/@description
/game/team/event[matches(@description, '^.*?doubles.*$')]/@description
/game/team/event[contains(@description, ' doubles ')]/@description
Комментарии:
1. Первые два не работали, когда я пробовал их в Java 1.6, я подозреваю, потому что XPath 2.0, по-видимому, недоступен. Третий вариант не вызвал никакого исключения, но, похоже, он не был сопоставлен с желаемыми узлами — ответ, который пришел обратно, был NaN . Но в любом случае большое спасибо.
Ответ №3:
Поскольку я просто пытаюсь сопоставить фрагмент значения атрибута description, можно использовать функцию XPath 2.0 ‘matches’, верно?
Да, при условии, что вы используете движок XPath 2.0 для вычисления выражения XPath.
Если бы вы должны были выполнить этот XPath с использованием движка XPath 2.0, он выбрал бы соответствующие @description
атрибуты.
Если да, то что я делаю не так?
Если вы используете движок XPath 2.0, ваша проблема может заключаться в том, что вы выбрали последовательность узлов, но ожидаете подсчета.
Если вы хотите вернуть количество этих атрибутов, вы могли бы использовать count()
функцию:
count(/game/team/event/@description[matches(.,' doubles ')])
Комментарии:
1. Функция matches (), похоже, недоступна в Java 1.6 (не то чтобы я действительно знал об этом заранее) — она вызывает исключение XPathExpressionException. Но в любом случае спасибо! Я ценю это.
2. Стандартные библиотеки Java 1.6 не поддерживают XPath 2.0, но Saxon и PsychoPath поддерживают.