为啥这个 xsl 从节点中写入文本

Posted

技术标签:

【中文标题】为啥这个 xsl 从节点中写入文本【英文标题】:why this xsl writes text out of nodes为什么这个 xsl 从节点中写入文本 【发布时间】:2019-07-23 15:18:38 【问题描述】:

在 xsl 文件中,我为 Prov 元素声明了一个模板。 xml 源还包含一个 Doc 元素,但没有此元素的模板。

为什么 xsl transofmation 会从 Doc 元素中写入一些内部文本?

嗨,这是 xml 输入

<Root>
  <Doc attr1="1" attr2="2" attr3="3">
    <node1 attr1="1" />
    <node2 attr1="2" />
    <node3 attr1="3" />
    <node4>1900-01-01T00:00:00Z</node4>
    <node5>1900-01-01T00:00:00Z</node5>
    <node6>
      <node7>
        <node8>xxx</node8>
        <node9>yyyy</node9>
        <node10>zzz</node10>
      </node7>
    </node6>
    <node11>xxx</node11>
    <node12>yyy</node12>
  </Doc>
  <Prov attr1="1" attr2="2" attr3="3" />
</Root>

我需要这个输出:

<Prov attr1="1" attr2="2" />

这是 xsl:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt">
  <xsl:output method="xml" encoding="ISO-8859-1" indent="yes"  />
  <xsl:template match="Prov" >
    <xsl:element name="Prov">
      <xsl:copy-of select="@attr1" />
      <xsl:copy-of select="@attr2" />
    </xsl:element>
  </xsl:template>
</xsl:stylesheet>

这是实际输出:

<?xml version="1.0" encoding="ISO-8859-1"?>




        1900-01-01T00:00:00Z
        1900-01-01T00:00:00Z


            xxx
            yyyy
            zzz


        xxx
        yyy

      <Prov attr1="1" attr2="2"/>

【问题讨论】:

【参考方案1】:

您看到的原因是built-in template rules。您只有一个匹配 Prov 的模板。这样一来,输入 XML 的整个 Doc 分支将由这些内置模板处理,这些模板会将所有文本节点复制到输出。

为了防止这种情况,您可以添加:

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

到您的样式表,或者 - 如果您愿意 - 将整个内容缩短为:

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

<xsl:template match="/Root" >
    <Prov attr1="Prov/@attr1" attr2="Prov/@attr2"/>
</xsl:template>

</xsl:stylesheet>

【讨论】:

以上是关于为啥这个 xsl 从节点中写入文本的主要内容,如果未能解决你的问题,请参考以下文章

从 XSL 中的命名空间节点获取子节点

为啥这个 xpath 匹配这个文本节点?

从XSL中的命名空间节点获取子节点

我无法从我的 xml 中以 xsl 编码获取子循环中的根节点数据

序列是如何拼接的,为啥我的变量值是文档节点?

XSL:在 XSL 1.0 中组合两个节点集