XSLT技术问题:如何在非根元素上显式展示默认命名空间
解决XML默认命名空间在子元素上显式展示的问题
我之前也碰到过一模一样的需求——明明给目标子元素加了和根节点完全一致的默认命名空间声明,结果输出里就是不显示。其实这是XML命名空间的自动优化机制在起作用:默认命名空间会从父元素(也就是你的根节点)自动继承,XSLT处理器在生成输出时,会自动去掉重复的命名空间声明,因为它知道这个子元素已经通过继承获得了该命名空间。
要让<MessageParts>元素显式输出默认命名空间,你可以用下面两种实用方法:
方法一:用<xsl:element>强制指定命名空间
直接使用XSLT的元素创建指令,显式指定命名空间,引导处理器保留这个声明:
<xsl:element name="MessageParts" namespace="http://schemas.microsoft.com/dynamics/2011/01/documents/Message"> <!-- 这里放入MessageParts的子节点内容 --> </xsl:element>
如果父元素的默认命名空间和这个完全一致,部分处理器可能还是会做优化,这时候可以配合给父元素临时设置一个不同的命名空间(如果业务允许的话),或者直接用下面的方法强制输出属性。
方法二:强制添加命名空间声明属性
通过<xsl:attribute>创建xmlns属性,并且指定它的命名空间为http://www.w3.org/2000/xmlns/(这是XML规范中专门用于命名空间声明的特殊命名空间),这样处理器就会把它识别为合法的命名空间声明,而不是普通属性:
<MessageParts> <xsl:attribute name="xmlns" namespace="http://www.w3.org/2000/xmlns/"> http://schemas.microsoft.com/dynamics/2011/01/documents/Message </xsl:attribute> <!-- 子节点内容 --> </MessageParts>
额外说明
虽然XML规范允许重复声明默认命名空间,但这其实是冗余的——标准的XML解析器完全能识别继承的命名空间。如果不是因为某些特定系统(比如旧版的自定义解析器)强制要求显式声明,其实没必要这么做。但如果确实有硬性需求,上面两种方法都能完美解决问题。
内容的提问来源于stack exchange,提问作者Leth
相关产品推荐
相关产品推荐

