使用 XSLT 重构节点

Restructure nodes using 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"进行正常重组。

这可以通过修改后的 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>

从恒等​​变换开始,它复制输入中出现的节点 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>