XSL:删除命名空间前缀
Posted
技术标签:
【中文标题】XSL:删除命名空间前缀【英文标题】:XSL: Remove namespace prefix 【发布时间】:2014-10-24 09:25:55 【问题描述】:搜索了一段时间后,我想我会在这里问。我正在尝试从 XSL 输出文件中删除空名称空间。让我提供相关代码:
输入 XML
<?xml version="1.0" encoding="UTF-8"?>
<DK_RequestChangeOfSupplier xmlns="un:unece:260:data:EEM-DK_RequestChangeOfSupplier:v2">
<HeaderEnergyDocument>
<Creation>Date</Creation>
</HeaderEnergyDocument>
</DK_RequestChangeOfSupplier>
XSL
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="un:unece:260:data:EEM-DK_RequestChangeOfSupplier:v2"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/">
<xsl:for-each select="ns1:DK_RequestChangeOfSupplier">
<McsDkSMBMsg
xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">
<xsl:call-template name="CreateElement">
<xsl:with-param name="ElementName" select="'Creation'" />
</xsl:call-template>
</McsDkSMBMsg>
</xsl:for-each>
</xsl:template>
<xsl:template name="CreateElement">
<xsl:param name="ElementName"></xsl:param>
<xsl:element name="$ElementName">Testing</xsl:element>
</xsl:template>
</xsl:stylesheet>
输出
<McsDkSMBMsg xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">
<Creation xmlns="">Testing</Creation>
</McsDkSMBMsg>
如何删除命名空间?我在 XSL 方面做错了什么吗?我慢慢地把头发拉出来。问候。
【问题讨论】:
您使用的是什么 XSLT 处理器?我无法重现您对 Saxon 或 Xalan 的问题。 XSL 不正确,已被编辑。您现在应该可以重现它了。 最简单的解决方法是将xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg"
声明移动到***xsl:stylesheet
元素上。
“感谢上帝,这个 XML 中有命名空间”,没有人说过...
【参考方案1】:
您的原始代码将两个元素添加到输出树中:一个名为 McsDkSMBMsg
的元素具有 默认命名空间:
<McsDkSMBMsg xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">
另一个是Creation
- 根据您的原始代码,它根本就在没有命名空间中。 XSLT 处理器确保Creation
元素不会出现在默认命名空间中的唯一方法是取消声明此命名空间:
<Creation xmlns="">Testing</Creation>
我假设您希望 Creation
元素也属于该默认命名空间。如果是这样,只需将相同的xmlns
属性添加到创建Creation
的xsl:element
指令。 XLST 处理器将处理任何多余的命名空间声明。
样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="un:unece:260:data:EEM-DK_RequestChangeOfSupplier:v2"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" omit-xml-declaration="no"/>
<xsl:template match="/">
<xsl:for-each select="ns1:DK_RequestChangeOfSupplier">
<McsDkSMBMsg
xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">
<xsl:call-template name="CreateElement">
<xsl:with-param name="ElementName" select="'Creation'" />
</xsl:call-template>
</McsDkSMBMsg>
</xsl:for-each>
</xsl:template>
<xsl:template name="CreateElement">
<xsl:param name="ElementName"></xsl:param>
<xsl:element name="$ElementName" xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">Testing</xsl:element>
</xsl:template>
</xsl:stylesheet>
XML 输出
现在xmlns
属性仅存在于McsDkSMBMsg
元素上。
<?xml version="1.0" encoding="UTF-8"?>
<McsDkSMBMsg xmlns="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg">
<Creation>Testing</Creation>
</McsDkSMBMsg>
也就是说,您的代码可能需要一些改进。您正在将 for-each
应用于最外层元素 - 其中只能有一个 - 这没有任何意义。此外,为新命名空间定义 prefix 可能更合理。而且您无缘无故地调用命名模板。
它的用处取决于实际的 XML 输入和您已有的其他代码。
改进的样式表
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="un:unece:260:data:EEM-DK_RequestChangeOfSupplier:v2"
xmlns:msg="http://schemas.microsoft.com/dynamics/2008/01/documents/McsDkSMBMsg"
exclude-result-prefixes="ns1">
<xsl:output method="xml" version="1.0" encoding="UTF-8"
indent="yes" omit-xml-declaration="no"/>
<xsl:template match="ns1:DK_RequestChangeOfSupplier">
<msg:McsDkSMBMsg>
<xsl:element name="msg:Creation">Testing</xsl:element>
</msg:McsDkSMBMsg>
</xsl:template>
</xsl:stylesheet>
【讨论】:
哈哈。那太棒了。我想我必须回到 XSL 和命名空间的基础知识。谢谢! @user2980567 不客气。还请看看我建议的改进 - 也许它们有用? 它们确实很有用。我的原始 XSL 文档和输入 XML 包含的数据比描述的要多,而且我还必须保持一些严格的标准。我一定会调查的。谢谢。以上是关于XSL:删除命名空间前缀的主要内容,如果未能解决你的问题,请参考以下文章