C# 添加使用命名空间的XElement

C# 添加使用命名空间的XElement,c#,C#,我在构造函数中创建了一个带有名称空间的XDocument,例如 this.nsXsl = XNamespace.Get("http://www.w3.org/1999/XSL/Transform"); this.doc = new XDocument( new XElement(nsXsl + "stylesheet", new XAttribute("version", "1.0"), new XAttribute(XNamespace.Xmlns + "xsl

我在构造函数中创建了一个带有名称空间的XDocument,例如

this.nsXsl = XNamespace.Get("http://www.w3.org/1999/XSL/Transform");
 this.doc = new XDocument(
               new XElement(nsXsl + "stylesheet", new XAttribute("version", "1.0"), new XAttribute(XNamespace.Xmlns + "xsl", "http://www.w3.org/1999/XSL/Transform"),
               new XElement(nsXsl + "output", new XAttribute("method", "xml"), new XAttribute("indent", "yes"), new XAttribute("encoding", "UTF-8")),
               new XElement(nsXsl + "strip-space", new XAttribute("elements", "*")))
               );
此文档具有正确的结构,看起来像我想要的

但我有一个函数,比如:

private XElement createTemplate(string match, string node, string fork, string select)
        {
            return new XElement(this.nsXsl + "template", new XAttribute("match", match), new XElement(node,
                new XElement(this.nsXsl + fork, new XAttribute("select", select))));

        }
此函数返回以下结构的元素:

<template match="/shiporder/shipto" xmlns="http://www.w3.org/1999/XSL/Transform">
  <Line1>
    <apply-templates select="city" xmlns="" />
  </Line1>
</template>

但我需要一个元素,比如:

<xsl:template match="/shiporder/shipto">
  <Line1>
    <xsl:apply-templates select="city" />
  </Line1>
</xsl:template>

有两点。首先,您的
Line1
元素用名称空间限定,而
apply templates
则不是,而您想要的是相反的。这是您自己做的:您在
new-XElement(this.nsXsl+node,
node
,我假定是
“Line1”
)中添加名称空间,而在
new-XElement(fork,
)中您忽略了这一点(显然,
fork
“应用模板”
)。只需将
this.nsXsl+/code>从前者移到后者

第二,您说您希望XSLT名称空间由前缀表示,
xsl
。前缀和名称空间之间的绑定是通过声明来设置的,声明以特殊形式
new-XAttribute(XNamespace.Xmlns+prefix,namespaceUri)
(您实际上在第一个代码段中就这样做了)。此绑定在声明它的元素和所有嵌套元素中有效,除非被另一个声明覆盖。当XML编写器发出具有命名空间限定名称的元素时,它检测到该命名空间绑定到前缀并使用该前缀(例如,在您的第一个代码片段中,名称空间
http://www.w3.org/1999/XSL/Transform
绑定到前缀
xsl
,因此XML编写器将
xsl:
前缀添加到所有嵌套元素)。如果XML编写器发现使用的命名空间未绑定到前缀,则会发出默认命名空间声明属性
xmlns=“名称空间”
(请注意,默认名称空间只影响元素,而不影响属性)

从XML信息模型的角度来看,以下三个片段是等效的:

<template match="/shiporder/shipto" xmlns="http://www.w3.org/1999/XSL/Transform">
  <Line1 xmlns="">
    <apply-templates select="city" xmlns="http://www.w3.org/1999/XSL/Transform" />
  </Line1>
</template>

<xsl:template match="/shiporder/shipto" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <Line1>
    <xsl:apply-templates select="city" />
  </Line1>
</template>

<weird:template match="/shiporder/shipto" xmlns:weird="http://www.w3.org/1999/XSL/Transform">
  <Line1>
    <weird:apply-templates select="city" />
  </Line1>
</template>


您想要的更改只是表面性的,新的XElement是如何/何时附加到XDoc的?@Henkholtman到目前为止,我有一个模板列表,并将添加它们,如` foreach(模板中的XElement元素){doc.add(elem);}`然后问题会自行解决。不要做任何事情。我同意第一点。对于您提到的第二点,只有通过添加
new XAttribute(XNamespace.Xmlns+前缀,namespaceUri),才能在我的标记名前面添加“xsl:”
到我的XElement?@StellaMaris,完全正确。就像在您的第一个代码片段中所做的那样。是否可以使用
XName nodeName=this.nsXsl+“模板”;XElemnet e=this.doc.Element(nodeName);
一些方法?@StellaMaris,非常好。