使用XSLT重组节点

时间:2015-01-06 02:45:50

标签: xslt

我有以下XML:

<myreport>
  <media>
    <assets>
      <asset>
        <type>image</type>
        <H>224 mm</H>
        <W>154 mm</W>
      </asset>
      <asset>
        <type>video</type>
        <H>480 px</H>
        <W>600 px</W>
      </asset>
    </assets>
</myreport>

我需要重组如下:

<myreport>
    <media>
        <assets>
            <image>
                <H>224 mm</H>
                <W>154 mm</W>
            </image>
            <video>
                <H>480 px</H>
                <W>600 px</W>
            <video>
        </assets>
    </media>
</myreport>

如何将类型与高度(H)宽度(W)匹配以实现所需的转换。我使用xsl:value-of select =“node”进行正常重组。

2 个答案:

答案 0 :(得分:1)

从身份转换开始,该转换会复制输入XML中显示的节点:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

asset元素添加特殊情况:

  <xsl:template match="asset">
    <xsl:element name="{type}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>

请注意,name={type}会根据子type元素的命名一个输出元素。

取消type元素:

  <xsl:template match="type"/>

澄清输出格式:

  <xsl:output method="xml" indent="yes"/>

<强>共

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
  <xsl:template match="asset">
    <xsl:element name="{type}">
      <xsl:apply-templates select="@*|node()"/>
    </xsl:element>
  </xsl:template>
  <xsl:template match="type"/>
</xsl:stylesheet>

答案 1 :(得分:0)

使用修改后的identity transform可以非常轻松地完成此操作。一个匹配asset元素而不是复制asset元素的模板,使用它的值类型元素作为要创建的元素的名称,然后将模板应用于其余部分它的孩子。一个(空)模板,它将禁止type元素和任何仅空白text()节点。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output indent="yes"/>

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

    <!--instead of an asset element, create an element named after it's type-->
    <xsl:template match="asset[type]">
        <xsl:element name="{type}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <!--suppress the type element and whitespace-only text nodes -->
    <xsl:template match="asset/type | text()[not(normalize-space())]"/>

</xsl:stylesheet>