非常熟悉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>
OUTPUT到XML文件戴帽子的猫Me
我需要输出为:
<books>
<book>
<name>Cat in the Hat</name>
<author>Me</author>
</book>
</books>
我做错了什么?
严格来说,运行输出时实际上会出现错误,因为MathiasMuller在评论中说,xsl:element
不能是顶级元素(即它不能是xsl;stylesheet
的直接子元素)。我猜Ecplise可能只是忽略了这一点。
但是,如果您只得到文本输出,那是因为XSLT的内置模板规则,当XML中没有任何匹配的模板时,该规则将用于匹配XML中的节点。实际上,这些只会跳过元素,并最终输出他们找到的任何文本节点。
如果您确实想从与输入相同的输出开始(如果您最终只想更改XML的一部分,这实际上是一种明智的方法),那么您应该从XSLT标识模板开始,它本身会按原样复制所有节点和属性(这意味着内置模板将不会被使用)。
<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>
然后,当您想要对输出进行更改时,只需要为想要更改的节点/属性编写模板。例如,假设您在book
元素下有一个想要删除的date
元素,那么您只需要添加这个模板
<xsl:template match="date" />
或者你可能想把name
重命名为title
,然后你可以做这个
<xsl:template match="name">
<title>
<xsl:apply-templates select="@*|node()"/>
</title>
</xsl:template>
请注意,如果您只是输出一个固定的元素名称,则不需要真正使用xsl:element
。