我想复制元素中的命名空间。命名空间属性及其值可能会有所不同,并且可能出现在任何元素中。但我想复制命名空间。此外,我不应该包含任何属性作为复制命名空间的附加内容。我正在使用Saxon 9(他)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>$</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>$</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>
答案 0 :(得分: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。
答案 1 :(得分:1)
详细说明Martin所说的内容:您正在对XML工具(如XSLT)提出要求,而这些要求并非旨在实现。
如果我们使用更精确的术语,这将有所帮助。您要求复制的不是名称空间,而是namespace declarations。
XML工具旨在能够在您指定的名称空间中生成指定的XML元素(和其他节点)。这是XML信息模型的一部分。 只要输出XML具有XML工具, 就不需要 来指定要使用的前缀,或者放置名称空间声明的位置正确名称空间中的正确元素和属性。
因此,任何下游XML使用者都不需要您指定的要求。也许如果你解释为什么你希望命名空间声明以某种方式出现,我们可以帮助你找到实现这些目的的方法,这些方法与XML命名空间的设计方式兼容。