如果子元素尚未具有相同的属性,则XSL将属性传递给子元素

时间:2013-08-05 10:23:35

标签: xslt attributes

如果子元素还没有相同的属性,我怎样才能将属性传递给子元素?

XML:

<section>
    <container attribute1="container1" attribute2="container2">
         <p attribute1="test3"/>
         <ol attribute2="test4"/>
    <container>
<section/>

输出应如下所示:

<section>
    <p attribute1="test3" attribute2="test2"/>
    <ol attribute1="container1" attribute2="test4"/>
</section>

这是我试过的:

<xsl:template match="container">
    <xsl:apply-templates mode="passAttributeToChild"/>
</xsl:template>

<xsl:template match="*" mode="passAttributeToChildren">
    <xsl:element name="{name()}">
        <xsl:for-each select="@*">
             <xsl:choose>
                  <xsl:when test="name() = name(../@*)"/>
                  <xsl:otherwise>
                      <xsl:copy-of select="."/>
                  </xsl:otherwise>
             </xsl:choose>
        </xsl:for-each>
        <xsl:apply-templates select="*|text()"/>
    </xsl:element>
</xsl:template>

非常感谢任何帮助;)提前感谢您!

2 个答案:

答案 0 :(得分:0)

试试这个。

<!-- root and static content - container -->
<xsl:template match="/">
    <section>
        <xsl:apply-templates select='section/container/*' />
    </section>
</xsl:template>

<!-- iteration content - child nodes -->
<xsl:template match='*'>
    <xsl:element name='{name()}'>
        <xsl:apply-templates select='@*|parent::*/@*' />
    </xsl:element>
</xsl:template>

<!-- iteration content - attributes -->
<xsl:template match='@*'>
    <xsl:attribute name='{name()}'><xsl:value-of select='.' /></xsl:attribute>
</xsl:template>

在输出每个子节点时,我们迭代地传递其属性和父节点的属性。

<xsl:apply-templates select='@*|parent::*/@*' />

模板按照它们在XML中出现的顺序应用于节点。所以父节点(container)节点出现在子节点之前(当然),所以它是父节点属性首先由属性模板处理。

这很方便,因为这意味着模板将始终显示子节点自身属性的首选项(如果它们已经存在),因为它们是最后处理的,因此优先于父节点中具有相同名称的任何属性。因此,父母不能否决他们。

{p> 工作演示 this XMLPlayground

答案 1 :(得分:0)

多次声明的属性会相互覆盖,所以这很容易。

<xsl:template match="container/*">
  <xsl:copy>
    <xsl:copy-of select="../@*" /> <!-- take default from parent -->
    <xsl:copy-of select="@*" />    <!-- overwrite if applicable -->
    <xsl:apply-templates />
  </xsl:copy>
</xsl:template>

这假设您需要所有父属性,如您的示例所示。当然,您可以决定要继承哪些属性:

    <xsl:copy-of select="../@attribute1 | ../@attribute2" />
    <xsl:copy-of select="@attribute1 | @attribute2">