我在构造函数中创建了一个带有名称空间的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>
答案 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"