我怎样才能像这样从XElement中去掉名称空间前缀(C#)

本文关键字:空间 前缀 像这样 XElement | 更新日期: 2023-09-27 18:19:52

我有一个这样的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>"

然后,当我从container元素中获得元素"Credentials"时,它会返回以下内容:

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

由于额外的命名空间,我无法将其反序列化为正确的Credentials对象。可以把它取下来吗?我试过如何删除命名空间前缀。(C#),该元素仍然有一个默认的命名空间。

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

我怎样才能像这样从XElement中去掉名称空间前缀(C#)

MSDN中有一篇文章可以根据您的需要进行调整:如何:更改整个XML树的命名空间

基本上,本文建议将树中每个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());

感谢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;
    }