XSLT:从子元素复制属性

时间:2011-03-16 21:50:27

标签: 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>

有人可以给我一份食谱吗?

2 个答案:

答案 0 :(得分:25)

易。

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

如果您不想再处理<xsl:apply-templates />的子女,则无需<a>

请注意

  • 使用<xsl:copy-of>将源节点插入到输出中
  • 使用union运算符|一次选择几个不相关的节点
  • 您可以将属性节点复制到新元素,只要它是您做的第一件事 - 在添加任何子元素之前。

编辑:如果您需要缩小您复制的属性的范围,以及您单独留下的属性,请使用此(或其变体):

<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(), '|'))
]" />

注意括号如何使谓词适用于所有匹配的节点。

答案 1 :(得分:6)

<强> 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>