如何使用 XSL 在 XML 文档中打印元素标签

How to print element tags in XML document using XSL

非常适合 XSL 初学者。我正在尝试将 2 XML 文档转换为新的 XML 文档。我似乎无法将标签打印到新文档中。只有元素的内容正在打印。

XML

<books>
  <book>
    <name>Cat in the Hat</name>
    <author>Me</name>
    ...
    ...
  </book>
  ...
  ...
</book>

XSL

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

    <xsl:template match="/">
        <xsl:apply-templates/>
    </xsl:template>

    <xsl:element name="books">
        <xsl:template match="books">
            <xsl:element name="book">
                <xsl:for-each select="book">
                    <xsl:element name="name"><xsl:value-of select="name"/></xsl:element>
                    <xsl:element name="author"><xsl:value-of select="author"/></xsl:element>
                </xsl:for-each>
            </xsl:element>
        </xsl:template>
    </xsl:element>

</xsl:stylesheet>

输出到 XML 文件 戴帽子的猫 我

我需要输出为:

<books>
  <book>
    <name>Cat in the Hat</name>
    <author>Me</author>
  </book>
</books>

我做错了什么?

严格来说,当你 运行 输出时你实际上得到了一个错误,因为 MathiasMuller 在评论中说,xsl:element 不能是顶级元素(即它不能是一个xsl;stylesheet 的直系子代)。我猜 Ecplise 可能只是忽略了这一点。

但是,如果您只获得文本输出,那是因为 XSLT 的 built-in template 规则,当 XML 中没有任何匹配的模板时,这些规则将用于匹配中的节点你的 XML。实际上,这些只会跳过元素,并最终输出它们找到的任何文本节点。

如果您确实希望从与输入相同的输出开始(如果您最终只想更改 XML 的一部分,这实际上是一种明智的方法),您应该从XSLT identity template,它会按原样复制所有节点和属性(这意味着不会使用内置模板)。

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

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

然后,当你想改变输出时,你只需要为你想改变的nodes/attributes编写模板。例如,假设您有一个要从 book 元素下删除的 date 元素,那么您只需添加此模板

<xsl:template match="date" />

或者您可能想将 name 重命名为 title 那么您可以这样做

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

请注意,如果您只是输出固定的元素名称,则没有必要使用 xsl:element