Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从XElement中去掉名称空间前缀,如(C#)?_C#_Xml_Xml Serialization - Fatal编程技术网

如何从XElement中去掉名称空间前缀,如(C#)?

如何从XElement中去掉名称空间前缀,如(C#)?,c#,xml,xml-serialization,C#,Xml,Xml Serialization,我有一个这样的xml字符串,我正在尝试将其反序列化为具有类凭据的对象。但是名称空间前缀阻止了我 Credentials类本身没有任何要设置命名空间的XmlRoot属性。但某些包含Credentials属性的类会这样做。下面的“ds”前缀来自容器的序列化xml 容器的xml如下所示: <ds:DataSource xmlns:ds="urn:My-Namespace"> <ds:Credentials> <ds:UserName>foo&

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

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 xmlns="urn:My-Namespace">
    <UserName>foo</UserName>
    <Domain>bar</Domain>
</Credentials>

福
酒吧

MSDN中有一篇文章可以根据您的需要进行修改:

基本上,本文建议将树中每个
XElement
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());
var xml=@”
福
酒吧
";
var tree1=XElement.Parse(xml);
foreach(树1.genderantsandself()中的XElement el)
{
el.Name=el.Name.LocalName;
列表atList=el.Attributes().ToList();
el.Attributes().Remove();
foreach(atList中的XAttribute at)
el.Add(新的XAttribute(at.Name.LocalName,at.Value));
}
//删除xmlns:ds=“urn:My Namespace”
树1.删除属性();
//将结果打印到控制台
Console.WriteLine(tree1.ToString());

感谢har07的灵感,我自己制定了解决方案,它将保留普通属性并删除其他名称空间:

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

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