скопировать узел, где присутствуют определенные атрибуты (или нет) - PullRequest
0 голосов
/ 02 мая 2018

У меня сейчас есть этот xsl, который отлично работает

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="node()">
        <xsl:copy copy-namespaces="no">
            <xsl:copy-of select="@Ccy"/>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

Это по существу переписывает мой XML, удаляя все атрибуты, кроме Ccy. Однако теперь мне нужно включить атрибуты с именем «имя». Я хотел бы объединить имена атрибутов, которые я хотел бы сохранить:

<xsl:copy-of select="@Ccy | @name"/>

Или, в идеале, скопировать все атрибуты, КРОМЕ

<xsl:copy-of select="!@BadAttyName"/>

Есть идеи ??

Ответы [ 3 ]

0 голосов
/ 02 мая 2018

XSLT 2.0 позволяет

<xsl:copy-of select="@* except @badAttName"/>

и, конечно, это также позволяет

<xsl:copy-of select="@* except @*[startswith(name(), 'badAttName')]"/>

Но в данном конкретном случае использование @*[not(....)] работает так же хорошо.

0 голосов
/ 02 мая 2018

XPath 2 и более поздние версии (это язык выражений, который вы используете с XSLT 2 и более поздними версиями), имеют оператор except, поэтому вы можете использовать, например, <xsl:copy-of select="@* except @foo"/> для копирования всех атрибутов, кроме атрибута foo или, например, <xsl:copy-of select="@* except (@foo, @bar)"/> для копирования всех атрибутов, кроме foo и bar one.

Поскольку вы хотите исключить атрибуты, начинающиеся с определенного префикса, вы можете использовать <xsl:copy-of select="@* except @*[matches(local-name(), '^BadAttyName')]"/>, хотя уже предложенное решение, отменяющее условие с помощью <xsl:copy-of select="@*[not(matches(local-name(), '^BadAttyName'))]"/>, более компактно и, вероятно, проще в этом случае.

0 голосов
/ 02 мая 2018

Вы можете использовать следующие таблицы стилей:

ВХОД:

$more input.xml 
<?xml version="1.0"?>
<a>
  <b Ccy="123" name="test1" BadAttyNameTest="toRemove1" BadAttyNameTestt="toRemovee1" other="hey1">toto</b>
  <b Ccy="456" name="test2" BadAttyNameTest="toRemove2" BadAttyNameTestt="toRemovee2" other="hey2">abc</b>
  <b Ccy="789" name="test3" BadAttyNameTest="toRemove3" BadAttyNameTestt="toRemovee3" other="hey3">uvw</b>
</a>

UNION:

::::::::::::::
inputUnion.xsl
::::::::::::::
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="node()">
        <xsl:copy copy-namespaces="no">
            <xsl:copy-of select="@Ccy | @name"/>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

СОЕДИНЕНИЕ ВЫХОДА:

$xsltproc inputUnion.xsl input.xml 
<a>
  <b Ccy="123" name="test1">toto</b>
  <b Ccy="456" name="test2">abc</b>
  <b Ccy="789" name="test3">uvw</b>
</a>

Будет скопировано только объединение атрибутов @Ccy | @name, остальные атрибуты не учитываются.

КРОМЕ:

::::::::::::::
inputNOT.xsl
::::::::::::::
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="node()">
        <xsl:copy copy-namespaces="no">
            <xsl:copy-of select="@*[not(starts-with(name(),'BadAttyName'))]"/>
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

ВЫХОД, КРОМЕ:

$xsltproc inputNOT.xsl input.xml 
<a>
  <b Ccy="123" name="test1" other="hey1">toto</b>
  <b Ccy="456" name="test2" other="hey2">abc</b>
  <b Ccy="789" name="test3" other="hey3">uvw</b>
</a>

синтаксис @*[not(starts-with(name(),'BadAttyName'))] будет принимать все атрибуты, которые удовлетворяют условию в скобках. Условием являются все элементы, которые не начинаются с BadAttyName, это создается путем объединения not() и starts-with().

...