XSLT: копирование атрибутов из дочернего элемента



Вход:



 <a q='r'>
<b x='1' y='2' z='3'/>
<!-- other a content -->
</a>


Желаемый результат:



 <A q='r' x='1' y='2' z='3'>
<!-- things derived from other a content, no b -->
</A>


Не мог бы кто-нибудь любезно дать мне рецепт?
731   2  

2 ответов:

Легко.

<xsl:template match="a">
  <A>
    <xsl:copy-of select="@*|b/@*" />
    <xsl:apply-templates /><!-- optional -->
  </A>
</xsl:template>

В <xsl:apply-templates /> нет необходимости, если у вас нет других детей <a>, которых вы хотите обработать.

Примечание

  • использование <xsl:copy-of> для вставки исходных узлов в выходные данные без изменений
  • использование оператора объединения | для выбора нескольких несвязанных узлов одновременно
  • что вы можете копировать узлы атрибутов в новый элемент до тех пор, пока это первое, что вы делаете - перед добавлением любых дочерних элементов.

Редактировать: Если вам нужно сузьте, какие атрибуты вы копируете, а какие оставляете в покое, используйте это (или его вариацию):

<xsl:copy-of select="(@*|b/@*)[
  name() = 'q' or name() = 'x' or name() = 'y' or name() = 'z'
]" />

Или даже

<xsl:copy-of select="(@*|b/@*)[
  contains('|q|x|y|z|', concat('|', name(), '|'))
]" />
Обратите внимание, как скобки делают предикат применимым ко всем соответствующим узлам.

XSL

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

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="a">
        <A>
            <xsl:apply-templates select="@*|b/@*|node()"/>
        </A>
    </xsl:template>

    <xsl:template match="b"/>

</xsl:stylesheet>

Вывод

<A q="r" x="1" y="2" z="3"><!-- other a content --></A>

Comments

    Ничего не найдено.