【问题标题】:How to print element tags in XML document using XSL如何使用 XSL 在 XML 文档中打印元素标签
【发布时间】:2015-02-23 08:32:29
【问题描述】:

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>

我做错了什么?

【问题讨论】:

  • 您能否将您期望的输出显示为实际的 XML,而不是文本表示,好吗?此外,您是否只是想在输出中为每本书显示nameauthor,而在book 元素之前忽略任何其他标签?谢谢!
  • 您是否使用 XSLT 处理器运行此程序?错误消息应该很容易理解。 xsl:element 不能是顶级元素。
  • 我已经添加了预期的输出......这与现在@TimC 的输入相同。
  • @MathiasMüller 是的,它已经通过 Eclipse 使用 XSLT 处理器运行。即使我删除了顶级元素,我仍然得到相同的输出。我只是不确定如何让标签显示。

标签: xml xslt xslt-1.0 xslt-2.0


【解决方案1】:

严格来说,您在运行输出时实际上会遇到错误,因为 MathiasMuller 在 cmets 中说,xsl:element 不能是顶级元素(即它不能是 xsl;stylesheet 的直接子元素)。我猜 Ecpise 可能只是忽略了这一点。

但是,如果您只获得文本输出,那是因为 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>

然后,当您想对输出进行更改时,您只需为要更改的节点/属性编写模板。例如,假设您希望从 book 元素下删除一个 date 元素,那么您只需添加此模板

<xsl:template match="date" />

或者,也许您想将 name 重命名为 title,然后您会这样做

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

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

【讨论】:

  • + 1,也许你可以添加几句话,如果没有与输入匹配的模板,为什么会输出所有文本?
  • 好主意!我在答案的开头添加了几段。谢谢!
  • 感谢@TimC。你给出了一个非常明确的答案,这对我理解有很大帮助:) 谢谢你付出了这么多的努力。
猜你喜欢
  • 1970-01-01
  • 2011-02-18
  • 2018-01-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多