xsl 命名空间从根复制到子节点,copy-namespaces="no" 不工作(xslt 3.0 版本)
xsl namespace from root copied to child node ,copy-namespaces="no" not working (xslt 3.0 version)
我正在尝试使用源 xml 的脚本,结果可在下面的 fiddle 工具 link
中找到
https://xsltfiddle.liberty-development.net/jxN9PRK/4
来源XML:
<root xmlns="http://www.oracle.com/retail/integration/rib/RibMessages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd">
<parent>test</parent>
<parentdtl>
<child xmlns="http://test.com">
<element1>1</element1>
</child>
</parentdtl>
<outer>T</outer>
</root>
使用的 XSL 脚本:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd"
exclude-result-prefixes="#all"
version="3.0">
<xsl:template match="*">
<xsl:variable name="copy-sans-namespaces" as="element()">
<xsl:copy-of select="." copy-namespaces="no"/>
</xsl:variable>
<xsl:variable name="ser-params" as="element()">
<output:serialization-parameters xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
<output:omit-xml-declaration value="yes" />
</output:serialization-parameters>
</xsl:variable>
<xsl:value-of select="serialize($copy-sans-namespaces, $ser-params)" />
</xsl:template>
<xsl:template match="*:root|*:parent|*:parentdtl|*:outer">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
预期输出:
<?xml version="1.0" encoding="UTF-8"?><root xmlns="http://www.oracle.com/retail/integration/rib/RibMessages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd">
<parent>test</parent>
<parentdtl>
<child xmlns="http://test.com">
<element1>1</element1>
</child>
</parentdtl>
<outer>T</outer>
</root>
相反,我收到了以下结果
<?xml version="1.0" encoding="UTF-8"?><root xmlns="http://www.oracle.com/retail/integration/rib/RibMessages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<parent>test</parent>
<parentdtl>
<child xmlns="http://test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<element1>1</element1>
</child>
</parentdtl>
<outer>T</outer>
</root>
在 XSL 脚本中遇到两个问题,
XSL 在转义时包括从根到其子名称空间之一。
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ,但是在转义 <child>
节点时不应包括在内,但 <child>
节点的原始名称空间应该是保留在转换中。
根中的命名空间并未全部复制到结果中XML。
xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd"
在结果 xml.
的父 <root>
节点中丢失
请分享任何指示,因为我是 XSLT 的新手。
XSL 版本是 3.0 并且在我正在处理的项目中使用 SAXON 9.6 引擎。
您在 Saxon 9.6 中获得的行为似乎是 Saxon 10.2 中仍然存在的错误,我在 https://saxonica.plan.io/boards/3/topics/8011 which lead to the bug issue https://saxonica.plan.io/issues/4793.
中查询过它
作为一种变通方法,我想您需要将元素推送到一个使用 xsl:element
进行复制的节点,避免命名空间复制:
<xsl:template match="*" mode="strip-in-scope-namespaces">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates mode="#current"/>
</xsl:element>
</xsl:template>
<xsl:template match="*">
<xsl:variable name="copy-sans-namespaces" as="element()">
<xsl:apply-templates select="." mode="strip-in-scope-namespaces"/>
</xsl:variable>
<xsl:variable name="ser-params" as="element()">
<output:serialization-parameters xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
<output:omit-xml-declaration value="yes" />
</output:serialization-parameters>
</xsl:variable>
<xsl:value-of select="serialize($copy-sans-namespaces, $ser-params)" />
</xsl:template>
https://xsltfiddle.liberty-development.net/jxN9PRK/5
至于xsi:schemaLocation
缺失,那是你忘记复制的属性;使用
<xsl:template match="*:root|*:parent|*:parentdtl|*:outer">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
我正在尝试使用源 xml 的脚本,结果可在下面的 fiddle 工具 link
中找到https://xsltfiddle.liberty-development.net/jxN9PRK/4
来源XML:
<root xmlns="http://www.oracle.com/retail/integration/rib/RibMessages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd">
<parent>test</parent>
<parentdtl>
<child xmlns="http://test.com">
<element1>1</element1>
</child>
</parentdtl>
<outer>T</outer>
</root>
使用的 XSL 脚本:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd"
exclude-result-prefixes="#all"
version="3.0">
<xsl:template match="*">
<xsl:variable name="copy-sans-namespaces" as="element()">
<xsl:copy-of select="." copy-namespaces="no"/>
</xsl:variable>
<xsl:variable name="ser-params" as="element()">
<output:serialization-parameters xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
<output:omit-xml-declaration value="yes" />
</output:serialization-parameters>
</xsl:variable>
<xsl:value-of select="serialize($copy-sans-namespaces, $ser-params)" />
</xsl:template>
<xsl:template match="*:root|*:parent|*:parentdtl|*:outer">
<xsl:copy>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
预期输出:
<?xml version="1.0" encoding="UTF-8"?><root xmlns="http://www.oracle.com/retail/integration/rib/RibMessages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd">
<parent>test</parent>
<parentdtl>
<child xmlns="http://test.com">
<element1>1</element1>
</child>
</parentdtl>
<outer>T</outer>
</root>
相反,我收到了以下结果
<?xml version="1.0" encoding="UTF-8"?><root xmlns="http://www.oracle.com/retail/integration/rib/RibMessages" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<parent>test</parent>
<parentdtl>
<child xmlns="http://test.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<element1>1</element1>
</child>
</parentdtl>
<outer>T</outer>
</root>
在 XSL 脚本中遇到两个问题,
XSL 在转义时包括从根到其子名称空间之一。 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ,但是在转义
<child>
节点时不应包括在内,但<child>
节点的原始名称空间应该是保留在转换中。根中的命名空间并未全部复制到结果中XML。 xsi:schemaLocation="http://mspdv170.us.oracle.com:7779/rib-func-artifact/integration/xsd/RibMessages.xsd" 在结果 xml.
的父<root>
节点中丢失
请分享任何指示,因为我是 XSLT 的新手。 XSL 版本是 3.0 并且在我正在处理的项目中使用 SAXON 9.6 引擎。
您在 Saxon 9.6 中获得的行为似乎是 Saxon 10.2 中仍然存在的错误,我在 https://saxonica.plan.io/boards/3/topics/8011 which lead to the bug issue https://saxonica.plan.io/issues/4793.
中查询过它作为一种变通方法,我想您需要将元素推送到一个使用 xsl:element
进行复制的节点,避免命名空间复制:
<xsl:template match="*" mode="strip-in-scope-namespaces">
<xsl:element name="{name()}" namespace="{namespace-uri()}">
<xsl:copy-of select="@*"/>
<xsl:apply-templates mode="#current"/>
</xsl:element>
</xsl:template>
<xsl:template match="*">
<xsl:variable name="copy-sans-namespaces" as="element()">
<xsl:apply-templates select="." mode="strip-in-scope-namespaces"/>
</xsl:variable>
<xsl:variable name="ser-params" as="element()">
<output:serialization-parameters xmlns:output="http://www.w3.org/2010/xslt-xquery-serialization">
<output:omit-xml-declaration value="yes" />
</output:serialization-parameters>
</xsl:variable>
<xsl:value-of select="serialize($copy-sans-namespaces, $ser-params)" />
</xsl:template>
https://xsltfiddle.liberty-development.net/jxN9PRK/5
至于xsi:schemaLocation
缺失,那是你忘记复制的属性;使用
<xsl:template match="*:root|*:parent|*:parentdtl|*:outer">
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:apply-templates />
</xsl:copy>
</xsl:template>