0

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

2 回答 2

1

详细说明 Martin 所说的内容:您对 XML 工具(如 XSLT)提出了它们并非旨在满足的要求。

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

XML 工具旨在能够在您指定它们所在的名称空间中生成指定的 XML 元素(和其他节点)。这是 XML 信息模型的一部分。只要输出 XML 在正确的名称空间中具有正确的元素和属性,XML 工具就不需要让您指定要使用的名称空间前缀或放置名称空间声明的位置。

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

于 2013-07-19T18:49:53.967 回答
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 没有办法防止这种情况发生。

于 2013-07-19T09:27:31.977 回答