无法在运行时将名称空间添加到XML
问题描述:
我有一个XML文件,我需要在运行时将名称空间应用于该文件。我搜索了网络,大多数例子似乎都建议使用“SetAttributeValue”函数。当我使用下面的代码时,它会抛出一个异常,当我尝试“ToString()”时出现以下错误:无法在运行时将名称空间添加到XML
The prefix '' cannot be redefined from '' to 'http://schemas.datacontract.org/2004/07/' within the same start element tag.
任何想法发生了什么问题?
XDocument data = XDocument.Parse("<Root><Stuff>Test</Stuff></Root>");
string ns = "http://schemas.datacontract.org/2004/07/";
data.Root.SetAttributeValue("xmlns",ns);
SaveFile(data.ToString());
答
你不能那样做。命名空间是DOM的基础。我现在唯一能想到的方法是在整个XML文本中使用String.Replace添加它,然后重新解析结果。
答
执行XSLT转换:
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns="your.target.default.namespace"
>
<!--
the "identity template" copies everything verbatim
-->
<xsl:template match="node() | @*">
<xsl:copy>
<xsl:apply-templates select="node() | @*" />
</xsl:copy>
</xsl:template>
<!--
this template creates new elements that
are in "your.target.default.namespace"
by default
-->
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="node() | @*" />
</xsl:element>
</xsl:template>
</xsl:stylesheet>
以上需要*命名空间的输入文档,并将其复制。只有元素节点被重新创建(通过第二个模板)。元素节点的
再创造使他们在命名空间中的XSLT样式表中,这里是“your.target.default.namespace”。
你的榜样,我会得到:
<Root xmlns="http://schemas.datacontract.org/2004/07/">
<Stuff>Test</Stuff>
</Root>
答
这些属性还缠着我前一段时间。我在创建简单的播客时使用XNamespace class解决了这个问题。以下是从我的应用程序示例代码:
XDocument xmlDocument = new XDocument(
new XDeclaration("1.0", "utf-8", "yes")
);
XNamespace itunesNamespace = "http://www.itunes.com/dtds/podcast-1.0.dtd";
XElement xmlRssElement = new XElement("rss", new XAttribute(XNamespace.Xmlns + "itunes", itunesNamespace), new XAttribute("version", "2.0"));
XElement xmlChannelElement = new XElement("channel",
new XElement("title", "title"),
new XElement(itunesNamespace + "explicit", "No"));
xmlRssElement.Add(xmlChannelElement);
xmlDocument.Add(xmlRssElement);
xmlDocument.Save(@"sample-" + DateTime.Now.Ticks + ".xml");
注意某些代码已被澄清去除
您可以让您的使用XDocument.Parse(原件),并从那里动态添加类似的命名空间在我的代码保存文档
答
默认命名空间之前做实际上是内在的的XElement,它不会让你通过操纵特性重新定义它。元素的名称空间作为其XName的一部分公开。所以要更改元素的名称空间,您必须重命名它。
XDocument data = XDocument.Parse("<Root><Stuff>Test</Stuff></Root>");
XNamespace ns = "http://schemas.datacontract.org/2004/07/";
data.Root.Name = ns + data.Root.Name.LocalName;
答
有点迟到了......
XNamespace ns = "http://schemas.datacontract.org/2004/07/";
XDocument xdoc = XDocument.Parse("<Root><Stuff>Test</Stuff></Root>");
foreach (var node in xdoc.Descendants()) { node.Name = ns + node.Name.LocalName; }
xdoc.Dump();
<Root xmlns="http://schemas.datacontract.org/2004/07/">
<Stuff>Test</Stuff>
</Root>