C# 向根元素添加名称空间
我正在编写一个XSLT转换,希望在根元素上定义所有名称空间前缀。默认情况下,MS似乎在XML层次结构中的第一个元素上创建一个新的前缀定义,以使用该模式;这意味着,如果多个元素与同一模式的共享祖先不相关,那么可以在多个元素上引用同一模式 通过对根元素进行这样的编码,所有元素都可以按需要工作:C# 向根元素添加名称空间,c#,.net,xslt,xslcompiledtransform,C#,.net,Xslt,Xslcompiledtransform,我正在编写一个XSLT转换,希望在根元素上定义所有名称空间前缀。默认情况下,MS似乎在XML层次结构中的第一个元素上创建一个新的前缀定义,以使用该模式;这意味着,如果多个元素与同一模式的共享祖先不相关,那么可以在多个元素上引用同一模式 通过对根元素进行这样的编码,所有元素都可以按需要工作: 然而,我找不到任何方法来使用xsl:element;e、 g http://another/schema 对于除元素本身之外的模式,是否可以针对xls:element声明名称空间前缀 完整示例 XM
然而,我找不到任何方法来使用xsl:element
;e、 g
http://another/schema
对于除元素本身之外的模式,是否可以针对xls:element
声明名称空间前缀
完整示例 XML
你好
世界
XSLT
结果
你好
世界
期望的结果
你好
世界
或
你好
世界
您的最小示例没有解释为什么需要使用xsl:element
而不是xsl:copy
和/或literal结果元素,但由于XSLT 1.0没有xsl:namespace
指令(),所以您唯一的方法是从样式表根复制名称空间节点,如中所示
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://some/schema"
xmlns:ns1 = "http://another/schema"
exclude-result-prefixes="xsl"
>
<xsl:output method="xml" indent="yes" version="1.0"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="document('')/*/namespace::*[. = 'http://another/schema']"/>
<xsl:apply-templates select="@* | node()" />
</xsl:element>
</xsl:template>
<xsl:template match="/ns0:Demo/ns0:a">
<xsl:element name="ns1:z">
<xsl:value-of select="./text()" />
</xsl:element>
</xsl:template>
<xsl:template match="/ns0:Demo/ns0:b">
<xsl:element name="ns1:y">
<xsl:value-of select="./text()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
(或具有该属性的任何其他节点,例如参数或变量,但通过这种方式,您还可以首先使用exsl:node set
或ms:node set
将结果树片段转换为节点集)
至于为什么literal结果元素和xsl:element会给出不同的结果,那么说:
创建的元素节点还将具有名称空间节点的副本
出现在样式表树中的元素节点上
虽然没有这样说。您的最小示例没有解释为什么需要使用
xsl:element
而不是xsl:copy
和/或literal-result元素,但是由于XSLT1.0没有xsl:namespace
指令(),所以您唯一的方法是从样式表根目录复制名称空间节点,如中所示
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns0="http://some/schema"
xmlns:ns1 = "http://another/schema"
exclude-result-prefixes="xsl"
>
<xsl:output method="xml" indent="yes" version="1.0"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/*">
<xsl:element name="{name(.)}" namespace="{namespace-uri(.)}">
<xsl:copy-of select="document('')/*/namespace::*[. = 'http://another/schema']"/>
<xsl:apply-templates select="@* | node()" />
</xsl:element>
</xsl:template>
<xsl:template match="/ns0:Demo/ns0:a">
<xsl:element name="ns1:z">
<xsl:value-of select="./text()" />
</xsl:element>
</xsl:template>
<xsl:template match="/ns0:Demo/ns0:b">
<xsl:element name="ns1:y">
<xsl:value-of select="./text()" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
(或具有该属性的任何其他节点,例如参数或变量,但通过这种方式,您还可以首先使用exsl:node set
或ms:node set
将结果树片段转换为节点集)
至于为什么literal结果元素和xsl:element会给出不同的结果,那么说:
创建的元素节点还将具有名称空间节点的副本
出现在样式表树中的元素节点上
虽然没有这样说。重要的是要理解,尽管它们通过名称空间声明属性在XML文档中表示,但在XPath和XSLT的数据模型中,每个元素的范围内名称空间是通过名称空间节点而不是属性节点建模的。此外,不同的元素不共享名称空间节点;每个都有自己的一套。使用XML输出方法时,XSLT处理器负责生成正确表示结果树中存在的命名空间节点的命名空间声明属性 这充分解释了为什么显式禁止通过
xsl:attribute
元素创建名称空间声明:
XSLT处理器可以使用QName的前缀
选择用于的前缀时在“名称”属性中指定
将创建的属性输出为XML;但事实并非如此
必须这样做,如果前缀是xmlns
,则它们不能这样做。
因此,尽管这样做不是错误:
<xsl:attribute name="xmlns:xsl" namespace="whatever">http://www.w3.org/1999/XSL/Transform</xsl:attribute>
另一方面,,如果必须通过
xsl:element
元素创建元素(只有在需要计算其名称时才需要该元素),则需要从输入树复制名称空间节点。重要的是要理解,尽管它们通过名称空间声明属性在XML文档中表示,在XPath和XSLT的数据模型中,每个元素的作用域内名称空间是通过名称空间节点而不是属性节点建模的。此外,不同的元素不共享名称空间节点;每个都有自己的一套。使用XML输出方法时,XSLT处理器负责生成正确表示结果树中存在的命名空间节点的命名空间声明属性
这充分解释了为什么显式禁止通过xsl:attribute
元素创建名称空间声明:
XSLT处理器可以使用QName的前缀
选择用于的前缀时在“名称”属性中指定
将创建的属性输出为XML;但事实并非如此
必须这样做,如果前缀是xmlns
,则它们不能这样做。
因此,尽管这样做不是错误:
<xsl:attribute name="xmlns:xsl" namespace="whatever">http://www.w3.org/1999/XSL/Transform</xsl:attribute>
另一方面,如果必须通过
xsl:element
元素创建元素(只有在需要计算其名称时才需要该元素),则需要从输入树复制名称空间节点。您可能希望向我们展示最小但完整的XML输入示例、XSLT代码、,你想要的结果和你得到的结果,让我们重现和理解问题。您在
中使用的代码片段似乎没有必要,因为您在运行时没有计算元素名称,所以我不确定您为什么需要xsl:element
。如果你愿意