【问题标题】:Copy elements with Namespaces using XSLT使用 XSLT 复制带有命名空间的元素
【发布时间】:2013-07-19 07:00:53
【问题描述】:

我想复制元素中的命名空间。命名空间属性及其值可能会有所不同,并且可以出现在任何元素中。但我想照原样复制名称空间。此外,我不应该包含任何属性作为复制命名空间的附加属性。我正在使用 Saxon 9(he) XSLT 处理器进行转换 在下面的 XML 文件中,我得到了缺少 "xmlns:ct-ext" 属性的元素 <ct-ext:case>。我试过copy-namespaces="yes",但我没有得到正确的输出。我正在为各种 DTD 编写通用 XSLT。

示例 XML:

<?xml version="1.0" encoding="UTF-8"?>
<ct:doc identifier="GPPCIA702661235" xsi:schemaLocation="http://test.com/test test.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ct="http://test.com/test" xmlns="http://www.w3.org/1998/Math/MathML" xmlns:ct-ext="http://test.com/test-ext">
<ct:doc-meta identifier="EHIXRW383636159">
<ct:para><ct:inline-math identifier="RCSNDD453018159"><math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>&#x0024;</mi><mn>1.65</mn></mrow></math></ct:inline-math></ct:para>
<ct-ext:case identifier="CDVOXU875594216" xmlns:ct-ext="http://test.com/test-ext">
<ct:simple-meta identifier="HNKRFT326435269">
<ct:title identifier="CGSVLX990515344">This is title</ct:title>
</ct:simple-meta>
</ct-ext:case>
</ct:doc-meta>
</ct:doc>

需要输出:

<?xml version="1.0" encoding="UTF-8"?>
<ct:doc identifier="GPPCIA702661235" xsi:schemaLocation="http://test.com/test test.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ct="http://test.com/test" xmlns="http://www.w3.org/1998/Math/MathML" xmlns:ct-ext="http://test.com/test-ext">
<ct:doc-meta identifier="EHIXRW383636159">
<ct:para><ct:inline-math identifier="RCSNDD453018159"><math xmlns="http://www.w3.org/1998/Math/MathML" display="inline"><mrow><mi>&#x0024;</mi><mn>1.65</mn></mrow></math></ct:inline-math></ct:para>
<ct-ext:case identifier="CDVOXU875594216" xmlns:ct-ext="http://test.com/test-ext">
<ct:simple-meta identifier="HNKRFT326435269">
<ct:title identifier="CGSVLX990515344">This is title</ct:title>
</ct:simple-meta>
</ct-ext:case>
</ct:doc-meta>
</ct:doc>

XSLT 试过了:

<?xml version='1.0'?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:m="http://www.w3.org/1998/Math/MathML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ct="http://test.com/test" xmlns="http://www.w3.org/1998/Math/MathML" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:mml="http://www.w3.org/1998/Math/MathML" xmlns:ct-ext="http://test.com/test-ext">
<xsl:output method="xml" encoding="UTF-8" indent="no"/>
<xsl:template match="@*|node()">
<xsl:copy copy-namespaces="yes">
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>

【问题讨论】:

    标签: xslt


    【解决方案1】:

    是否使用copy-namespaces 无关紧要(无论如何都是默认值),如果输入 XML 在内部元素节点上有重复的命名空间声明,那么 XSLT 处理器操作的数据模型与如果内部命名空间声明不存在,则生成一个。 所以

    <root xmlns:ct-ext="http://test.com/test-ext">
      <ct-ext:case xmlns:ct-ext="http://test.com/test-ext">...</ct-ext:case>
    </root>
    

    没有区别
    <root xmlns:ct-ext="http://test.com/test-ext">
      <ct-ext:case>...</ct-ext:case>
    </root>
    

    因此,在序列化复制的结果树时,最初复制的命名空间声明会丢失。我认为 XSLT 没有办法防止这种情况发生。

    【讨论】:

    • 感谢您的回复。
    【解决方案2】:

    详细说明 Martin 所说的:您对 XML 工具(如 XSLT)提出了一些要求,而这些要求并非旨在满足这些要求。

    如果我们使用更精确的术语会有所帮助。您要复制的不是命名空间,而是namespace declarations

    XML 工具旨在能够在您指定它们所在的名称空间中生成指定的 XML 元素(和其他节点)。这是 XML 信息模型的一部分。 只要输出 XML 具有正确命名空间中的正确元素和属性。

    因此,任何下游 XML 使用者都不需要您指定的要求。也许如果您解释为什么您希望命名空间声明以某种方式出现,我们可以帮助您找到实现这些目的的方法,这些方法与 XML 命名空间的设计工作方式兼容。 p>

    【讨论】:

      猜你喜欢
      • 2014-02-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-24
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多