无法在运行时向XML添加命名空间

时间:2009-10-22 14:55:04

标签: .net xml namespaces

我有一个XML文件,我需要在运行时应用命名空间。我搜索过网络,大多数例子似乎建议使用“SetAttributeValue”函数。当我使用下面的代码时,当我尝试使用以下错误“ToString()”时抛出异常:

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());

5 个答案:

答案 0 :(得分:2)

派对有点晚......

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> 

答案 1 :(得分:1)

进行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>

答案 2 :(得分:1)

默认命名空间实际上是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;

答案 3 :(得分:0)

你做不到。命名空间是DOM的基础。我现在能想到的唯一方法是使用String.Replace在整个XML文本上添加它,然后重新解析结果。

答案 4 :(得分:0)

这些属性也在前段时间困扰我。我在创建简单播客时使用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()获取原始文档,并从那里动态添加命名空间,就像在保存文档之前在我的代码中完成一样