我有一个要求如下:
如果我输入为:
<?xml version="1.0"?>
<new:NewAddressData xmlns:new="http://www.example.org/NewAddress">
<new:NewStreet></new:NewStreet>
<new:NewArea>Area_1</new:NewArea>
<new:NewState></new:NewState>
</new:NewAddressData>
输出应为:
<new:NewArea>Area_1</new:NewArea>
实际上我是XSLT的新手,但我阅读了一些基础知识并尝试了以下代码:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<!-- identity transform -->
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:choose>
<xsl:when test="@*|node() != ''">
<xsl:value-of select="." disable-output-escaping="yes" />
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="@*|node()"/>
</xsl:otherwise>
</xsl:choose>
</xsl:copy>
</xsl:template>
为此,我得到的输出为:
<new:NewAddressData xmlns:new="http://www.example.org/NewAddress">Area_1</new:NewAddressData>
其中期望值应如下所示:
<new:NewArea>Area_1</new:NewArea>
那么如何使用 XSLT 1.0 实现这一点
提前致谢
你可以做这样的事情:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="*[text()]">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
根据输入,例如,如果有多个元素包含文本,这可能会导致输出格式不正确。
看起来您已经阅读了有关 XSLT 标识模板的信息,这很好!
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
就其本身而言,这将复制到所有不变的节点(例如您的 NewArea
元素),因此您需要为要更改的内容编写模板。在这种情况下,您似乎要删除没有非空文本节点的元素作为子节点。
<xsl:template match="*[not(text()[normalize-space()])]">
试试这个 XSLT
<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="*[not(text()[normalize-space()])]">
<xsl:apply-templates />
</xsl:template>
</xsl:stylesheet>
这将输出以下内容
<new:NewArea xmlns:new="http://www.example.org/NewAddress">Area_1</new:NewArea>
此处需要命名空间。不能在不声明与其关联的命名空间的情况下输出带有前缀的元素。