【问题标题】:XElement Add function adds xmlns="" to the XElementXElement Add 函数将 xmlns="" 添加到 XElement
【发布时间】:2011-01-18 17:26:15
【问题描述】:

我有一个为列表对象生成 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>

所以由于某种原因添加了一个空的命名空间,我该如何防止它这样做?

【问题讨论】:

    标签: c# .net xml xml-serialization linq-to-xml


    【解决方案1】:

    这是一个输出没有空命名空间的 xml 的示例。注意奇怪的以 Linq 为中心的语法 rootNamespace + "MyElementName",这是秘密。这是与整个文档相同的命名空间,因此不需要添加 xmlns。这是连接一个 XNamespace + 一个字符串,这是一个适用于 Linq 并且 Linq 知道如何处理的“+”重载。 (如果没有 Linq,连接字符串和非字符串类型可能是编译错误)。请注意,这是针对一个方便的 Xml 文件的 C# 项目文件执行的。将其输出到控制台或富文本框控件。然后取出“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);
    

    【讨论】:

    • 谢谢,这看起来是一个非常好的解决方案!下次遇到这个问题我会试试的。
    • 谢谢!这很有帮助!
    • 谢谢。这太棒了! +1
    【解决方案2】:

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

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

    【讨论】:

      【解决方案3】:

      我通过用正则表达式替换元素来解决它。傻瓜的解决方案不起作用,因为我现在并不总是在代码中那个点的确切名称空间。

      所以这是我的肮脏技巧:

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

      【讨论】:

      • 小心你的正则表达式。 XML 不是正则语言,因此一般来说,不应该对 XML 使用正则表达式。
      【解决方案4】:

      将 Example 和 SubElement 元素上的命名空间设置为与 RootElement 相同。它正在添加 xmlns="" 以清除这些元素的命名空间。

      【讨论】:

      • 好的,我现在明白为什么会这样了,谢谢!但它仅在您合并具有不同名称空间的不同 xml 时才有用,而不是在创建单个 xml 文档时。此外,空的命名空间标记不是有效的 xml。
      • @JJoos:空的命名空间肯定是有效的 XML。是什么让你认为不是?另外,请记住,单个 XML 文档可能包含来自多个命名空间的元素和属性。
      • @John Saunders 你是对的,认为这是非法的,因为:w3.org/TR/REC-xml-names 第 2.2 节第一行。有点混乱。谢谢。
      猜你喜欢
      • 1970-01-01
      • 2011-08-22
      • 1970-01-01
      • 2019-03-27
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 1970-01-01
      • 2014-08-28
      相关资源
      最近更新 更多