Сохранение приоритета операндов в однострочном Xpath 1.0 - PullRequest
3 голосов
/ 08 января 2011

Я не могу сформулировать это правильно, лучше с примером.

XML:

<?xml version="1.0" encoding="UTF-8"?>
<foo>
    <bar id="someId" class="someClass"/>
    <buz class="someClass" id="someId"/>
    <ololo class="someClass"/>
    <test id="someId"/>
</foo>

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/*/*">
    <xsl:value-of select="@id | @class"/><xsl:text>&#xa;</xsl:text>
</xsl:template>

</xsl:stylesheet>

Результат:

someId
someClass
someClass
someId

Что мне нужно

Мне нужно, чтобы «приоритет» атрибутов оставался таким, как указано в моем выражении xpath.

Итак, если мы назовем @id | @class выражением с двумя операндами, мне нужно, чтобы атрибуты были взяты не в порядке документа, а в порядке того, как два операнда были указаны в выражении.

Итак, результат должен быть :

someId
someId
someClass
someId

@class следует принимать, только если @id отсутствует.

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

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

Обратите внимание, что я говорю в терминах XPath 1.0 .

1 Ответ

3 голосов
/ 08 января 2011

Используйте

@id | @class[not(../@id)]

Это выражение XPath всегда выбирает один узел : @id, если он существует, и только если @id не существует, то @class.

Итак, это преобразование :

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:strip-space elements="*"/>

 <xsl:output method="text"/>

 <xsl:template match="foo/*">
  <xsl:value-of select="@id | @class[not(../@id)]"/>
  <xsl:text>&#xA;</xsl:text>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<foo>
    <bar id="someId" class="someClass"/>
    <buz class="someClass" id="someId"/>
    <ololo class="someClass"/>
    <test id="someId"/>
</foo>

дает желаемые, правильные результаты :

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