如何使用 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
。
非常适合 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
。