添加使用命名空间的XElement

时间:2016-08-08 10:01:04

标签: 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", "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))));

        }

此函数返回以下结构的XElement:

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

但我需要一个XElement,如:

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

1 个答案:

答案 0 :(得分:1)

有两点。首先,您的Line1元素使用命名空间限定,apply-templates不符合,而您想要的是相反的。这是你自己做的:你在new XElement(this.nsXsl + node, …node,我认为是"Line1")中添加名称空间,而你在new XElement(fork, …中省略了这一点(显然,fork"apply-templates")。只需将this.nsXsl +从前者移到后一位。

其次,您说您希望XSLT命名空间用前缀xsl表示。前缀和名称空间之间的绑定是通过以特殊形式new XAttribute(XNamespace.Xmlns + prefix, namespaceUri)的属性形式表示的声明来设置的(您实际上是在第一个代码段中执行此操作)。此绑定在声明它的元素和所有嵌套元素中有效,除非由另一个声明进行溢流。当XML编写器发出具有名称空间限定名称的元素时,它会检测到该名称空间绑定到前缀并使用该前缀(例如,在您的第一个代码段中,名称空间http://www.w3.org/1999/XSL/Transform绑定到前缀{{1}因此,XML编写器将xsl前缀添加到所有嵌套元素中。如果XML编写器发现使用的命名空间未绑定到前缀,则会为您发出默认的命名空间声明属性xsl:(请注意,默认命名空间仅影响元素,而不影响属性)。

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

xmlns="namespace"