XSLT将子元素转换为父元素的属性

时间:2015-09-21 21:40:34

标签: xml xslt

<?xml version="1.0"?>
<parent id="38" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <child id="1" colorType="firstColor" colorKey="blue"/>
  <child id="2" colorType="secondColor" colorKey="red"/>
</parent>

所以我有以前的XML,我想用以下方式使用XSLT对其进行转换:

<?xml version="1.0"?>
<parent id="38" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
firstColor="blue" secondColor="red">
</parent>

因此,子元素中的两个值将用作父元素中的pair属性,从而删除流程中的子元素。我尝试了但不能绕过似乎是XSLT的基础知识。

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="parent">
    <parent>
      <xsl:apply-templates/>
    </parent>
  </xsl:template>

  <xsl:template match="parent">
    <parent>
      <xsl:attribute name="{@colorType}">
        <xsl:value-of select="@colorKey"/>
      </xsl:attribute>
     </parent>
  </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:2)

您位于正确的行,但实际上您需要为child下的每个parent元素创建一个属性,因此您可以在此使用xsl:for-each

尝试将parent模板替换为:

<xsl:template match="parent">
    <xsl:copy>
        <xsl:copy-of select="@*"/>
        <xsl:for-each select="child">
            <xsl:attribute name="{@colorType}">
                <xsl:value-of select="@colorKey" />
            </xsl:attribute>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

另请注意使用xsl:copy-of复制现有属性。另请注意使用<xsl:copy>而不是仅执行<parent>,因为这将确保复制“xsi”的名称空间声明。

答案 1 :(得分:1)

我会选择以下内容,即只需将模板应用到child并进行匹配,这样每个孩子都会变成属性:

<xsl:template match="parent">
    <xsl:copy>
        <xsl:copy-of select="@*" />
        <xsl:apply-templates select="child" />
    </xsl:copy>
</xsl:template>

<xsl:template match="child">
    <xsl:attribute name="{@colorType}" select="@colorKey" />
</xsl:template>

我通常更喜欢将模板应用于每个节点上的每个节点,因为以后通常更容易适应,并且(通常)更容易理解。