使用 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>
我有以下 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>