XElement的Add函数会向XElement中添加xmlns=""。

8
我有一个函数,用于生成列表对象的xml:
public XDocument ToXML()
{
    foreach (var row in this)
    {
        var xml = row.ToXml();
        template.Root.Add(xml);
    }
    return template;
}

template.ToString() 的输出结果为:<RootElement xmlns="urn:testTools">

xml 的输出结果为:<Example><SubElement>testData</SubElement></Example>

执行添加函数后,template.ToString() 的输出结果变为:<RootElement xmlns="urn:testTools"><Example xmlns=""><SubElement>testData</SubElement></Example>

因此,某种原因导致添加了一个空的命名空间,请问如何避免这种情况发生?

4个回答

9
这是一个输出没有空名称空间的xml示例。请注意奇怪的Linq中心语法rootNamespace +“MyElementName”,这是秘密所在。这与整个文档的相同名称空间相同,因此不需要添加xmlns。这是将XNamespace和字符串连接起来的“+”重载,适用于Linq,并且Linq知道如何处理它。(没有Linq,连接字符串和非字符串类型可能会导致编译错误)。请注意,这是针对C#项目文件执行的Xml文件。将其输出到控制台或richtextbox控件中。然后删除“rootNamespace +”并注意差异。
        XDocument doc = null;

        using (StreamReader streamReader =
            new StreamReader(@"myXml.csproj"))
        {
            doc = XDocument.Load(streamReader, LoadOptions.None);
        }
        XNamespace rootNamespace = doc.Root.Name.NamespaceName;

        // A search which finds the ItemGroup which has Reference 
        // elements and returns the ItemGroup XElement.
        XElement element = doc.Descendants().Where(p => p.Name.LocalName == "ItemGroup"
            && p.Descendants().First<XElement>().Name.LocalName == "Reference").First<XElement>();

        // Create a completly new element with sub elements.
        XElement referenceElement = new XElement(rootNamespace + "Reference",
            new XElement(rootNamespace + "SpecificVersion", bool.FalseString),
            new XElement(rootNamespace + "HintPath", "THIS IS A HINT PATH"));

       // Add the new element to the main doc, to the end of the Reference elements.
        element.Add(referenceElement);

        // Add an attribute after the fact for effect.
        referenceElement.SetAttributeValue("Include", "THIS IS AN INCLUDE");

        rtb.Text = doc.ToString(SaveOptions.None);

谢谢,这看起来是一个非常好的解决方案!下次遇到这个问题时我会试一试。 - JJoos
1
谢谢。这太棒了!+1 - Umar Farooq Khawaja

8
将示例元素和子元素的名称空间设置为与根元素相同。 添加 xmlns = "" 以清除这些元素的名称空间。

好的,我现在明白它为什么这样做了,谢谢!但是只有在合并具有不同命名空间的不同xml时才有用,而不是创建单个xml文档时。此外,空命名空间标记不是有效的xml。 - JJoos
1
@JJoos:一个空的命名空间确实是有效的XML。你为什么认为它无效呢?此外,请记住,单个XML文档可能具有来自许多命名空间的元素和属性。 - John Saunders
@John Saunders 你是对的,我之前认为它是非法的,是因为: http://www.w3.org/TR/REC-xml-names/ 第2.2节第一行。有点令人困惑。谢谢。 - JJoos

0

可能是因为您的根需要正确关闭:

 <RootElement xmlns="urn:testTools"> to <RootElement xmlns="urn:testTools"/> 

0

我通过使用正则表达式替换元素来解决了这个问题。Foole的解决方案不起作用,因为在代码的那一点,我并不总是知道确切的命名空间。

所以这是我的脏解决方案:

template = XDocument.Parse(new Regex("<ElementName.*>")
    .Replace(template.ToString(SaveOptions.DisableFormatting), "<ElementName>"));

4
小心使用正则表达式。XML不是一种正则语言,因此通常情况下,不应该对XML使用正则表达式。 - John Saunders

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接