Как выбрать логически значимые узлы в XPath? - PullRequest
5 голосов
/ 13 июля 2009

У меня есть документ XML и связанная схема, в которой несколько атрибутов определены как имеющие тип xs:boolean. Лексические значения для xs:boolean: true, false, 1 и 0, поэтому для правильного выбора атрибутов с определенным логическим значением мне нужно написать что-то вроде:

@attribute='true' or @attribute='1'

или

@attribute='false' or @attribute='0'

Это кажется многословным.

Можно ожидать, что сработает что-то вроде boolean(@attribute), но функция boolean имеет другую семантику.

Есть ли лучший способ? Может ли это помочь процессор с поддержкой схемы?

Ответы [ 6 ]

6 голосов
/ 14 июля 2009

В дополнение к решениям, предложенным Филом и Томалаком, я обнаружил, что XPath 2.0 предоставляет несколько альтернатив:

@attribute=('true','1')
string(@attribute) cast as xs:boolean

И, наконец, XPath 2.0 обеспечивает обработку с учетом схемы, что означает, что если все выровнено, вы должны написать:

data(@attribute)

Но процессоры с поддержкой схемы, похоже, трудно найти. Самым популярным представляется несвободный коммерческий вариант саксон , который стоит £ 300. Так что сейчас я использую @attribute=('true','1').

3 голосов
/ 05 февраля 2014

Попробуйте следующее выражение XPath:

[@attribute=true()]
1 голос
/ 14 июля 2009

Я использую простой именованный шаблон, который выполняет подробную проверку и настраивает его по мере необходимости для работы с устаревшими системами (например, некоторые поля могут использовать «Y» / «N», некоторые «True» / «False», другие 1/0 ) и сбросьте значение в переменную. Это не самый элегантный подход, но если вы используете XPath 1.0, не имеете поддержки EXSLT и не можете (или не хотите) использовать внешние вызовы скрипта, он работает согласованно и может быть настроен по мере необходимости.

<xsl:template name="CleanupBool">
    <xsl:param name="val" />
    <xsl:choose>
        <xsl:when test="$val='1'">1</xsl:when>
        <xsl:when test="$val='true'">1</xsl:when>
        <xsl:when test="$val='True'">1</xsl:when>
        <xsl:when test="$val='TRUE'">1</xsl:when>
        <xsl:when test="$val='T'">1</xsl:when>
        <xsl:when test="$val='Y'">1</xsl:when>
        <xsl:otherwise>0</xsl:otherwise>
    </xsl:choose>
</xsl:template>

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

<xsl:variable name="enabled">
    <xsl:call-template name="CleanupBool">
        <xsl:with-param name="val" select="IS_ENABLED"/>
    </xsl:call-template>
</xsl:variable>
1 голос
/ 13 июля 2009

Используя только XPath, предлагаемое вами выражение максимально близко. Существуют разные способы выполнения одной и той же проверки, но все они приведут к более длинному и сложному выражению и будут скрывать намерение больше.

Я не думаю, что есть процессор с поддержкой схемы, схема XML не подключена к XSLT, и было бы бессмысленно встраивать его поддержку в процессор, ИМХО. Язык определен, и расширения являются общепринятым стандартным способом добавления функциональности.

Если используемая вами библиотека поддерживает функции расширения EXSL, вы можете написать полупортативный механизм для абстрагирования логической проверки в функцию или использовать для этого специфичные для поставщика расширения, такие как MSXSL.

Я думаю, что лучше остаться с выражением, которое у вас есть. Это не запутано, только немного многословно.

1 голос
/ 13 июля 2009

Ваши параметры могут зависеть от того, какой процессор XPath вы используете. Например, материал Microsoft позволяет вам определять функции JavaScript, которые вы могли бы использовать для реализации шаблона «boolean (@attribute)». Я не знаю, могут ли другие движки иметь подобную поддержку.

В противном случае, я подозреваю, что вы застряли с необходимостью проверить как «true», так и «1».

Надеюсь, у кого-то есть лучший ответ.

0 голосов
/ 07 мая 2014

@attribute cast as xs:boolean хороший способ сделать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...