【问题标题】:How can I get rid of the namespace prefix from XElement like this (C#)?我怎样才能像这样 (C#) 摆脱 XElement 的命名空间前缀?
【发布时间】:2014-08-29 06:22:41
【问题描述】:

我有一个这样的 xml 字符串,我正在尝试将其反序列化为具有类 Credentials 的对象。但是命名空间前缀阻止了我。

Credentials 类本身没有任何 XmlRoot 属性来设置命名空间。但是某些包含 Credentials 属性的类可以。而下面的“ds”前缀来自容器的序列化xml。

容器的xml是这样的:

<ds:DataSource xmlns:ds="urn:My-Namespace">
    <ds:Credentials>
        <ds:UserName>foo</ds:UserName>
        <ds:Domain>bar</ds:Domain>
    </ds:Credentials>
</ds:DataSource>"

然后,当我从容器元素中获取元素“凭据”时,它会返回:

<ds:Credentials xmlns:ds="urn:My-Namespace">
    <ds:UserName>foo</ds:UserName>
    <ds:Domain>bar</ds:Domain>
</ds:Credentials>

由于额外的命名空间,我无法将其反序列化为正确的 Credentials 对象。这样可以去掉吗?我试过How to remove namespace prefix. (C#),该元素仍然有一个默认命名空间。

<Credentials xmlns="urn:My-Namespace">
    <UserName>foo</UserName>
    <Domain>bar</Domain>
</Credentials>

【问题讨论】:

    标签: c# xml xml-serialization


    【解决方案1】:

    MSDN中有一篇文章可以改编为你想做的事:How to: Change the Namespace for an Entire XML Tree

    基本上这篇文章建议将树中每个XElementName 更改为新的Name(仅供参考,Name 属性包含有关命名空间和本地名称的信息)。在这种情况下,由于我们要将每个元素都更改为无命名空间,您可以将Name更改为对应的Name.LocalName

    var xml = @"<ds:DataSource xmlns:ds=""urn:My-Namespace"">
        <ds:Credentials>
            <ds:UserName>foo</ds:UserName>
            <ds:Domain>bar</ds:Domain>
        </ds:Credentials>
    </ds:DataSource>";
    var tree1 = XElement.Parse(xml);
    foreach (XElement el in tree1.DescendantsAndSelf())
    {
        el.Name = el.Name.LocalName;
        List<XAttribute> atList = el.Attributes().ToList();
        el.Attributes().Remove();
        foreach (XAttribute at in atList)
            el.Add(new XAttribute(at.Name.LocalName, at.Value));
    }
    //remove xmlns:ds="urn:My-Namespace"
    tree1.RemoveAttributes();
    //print result to console
    Console.WriteLine(tree1.ToString());
    

    【讨论】:

    • 谢谢,代码似乎会删除所有元素的所有属性,包括不是命名空间的属性。
    • 是的,我尽量不要使解决方案过于复杂,因为发布的示例除了命名空间前缀属性之外没有任何属性。无论如何,很高兴看到您自己提出了解决方案
    【解决方案2】:

    感谢 har07 和 http://bohu7.wordpress.com/2008/12/11/removing-default-namespaces-from-an-xdocument/ 的启发,我自己制定了解决方案,它会保留正常属性并删除其他命名空间:

        public static void RemoveNamespace(this XElement element)
        {
            foreach (XElement e in element.DescendantsAndSelf())
            {
                if (e.Name.Namespace != XNamespace.None)
                    e.Name = e.Name.LocalName;
    
                if (e.Attributes().Any(a => a.IsNamespaceDeclaration || a.Name.Namespace != XNamespace.None))
                    e.ReplaceAttributes(e.Attributes().Select(NoNamespaceAttribute));
            }
        }
    
        private static XAttribute NoNamespaceAttribute(XAttribute attribute)
        {
            return attribute.IsNamespaceDeclaration
                ? null
                : attribute.Name.Namespace != XNamespace.None
                    ? new XAttribute(attribute.Name.LocalName, attribute.Value)
                    : attribute;
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-12-26
      • 2012-10-11
      • 1970-01-01
      相关资源
      最近更新 更多