c# - - - 如何将XML命名空间提升到root元素

如果我有一个包含命名空间的XML文件,如:


<root>



<h:table xmlns:h="http://www.namespaces.com/namespaceOne">


 <h:tr>


 <h:td>Apples</h:td>


 <h:td>Bananas</h:td>


 </h:tr>


</h:table>



<h:table xmlns:h="https://www.namespaces.com/namespaceTwo">


 <h:name>African Coffee Table</f:name>


 <h:width>80</f:width>


 <h:length>120</f:length>


</h:table>



</root>



我想将所有名称空间提升到root元素,如下所示:


<root xmlns:h="http://www.namespaces.com/namespaceOne" xmlns:h1="https://www.namespaces.com/namespaceTwo">



<h:table>


 <h:tr>


 <h:td>Apples</h:td>


 <h:td>Bananas</h:td>


 </h:tr>


</h:table>



<h1:table>


 <h1:name>African Coffee Table</f:name>


 <h1:width>80</f:width>


 <h1:length>120</f:length>


</h1:table>



</root>



有什么方法可以做到?

时间:

这非常简单:


var doc = XDocument.Parse(xml);


var namespaceAttributes = doc.Descendants()


 .SelectMany(x => x.Attributes())


 .Where(x => x.IsNamespaceDeclaration);


int count = 1;


foreach (var namespaceAttribute in namespaceAttributes)


{


 doc.Root.Add(new XAttribute(XNamespace.Xmlns + $"h{count}", namespaceAttribute.Value));


 namespaceAttribute.Remove();


 count++;


}



我们遍历所有名称空间声明(xmlns:foo="foo" ),对于我们找到的每个名称空间属性,我们在root元素上放置一个URL相同的名称空间属性,并删除这个属性。

注意,这不会折叠有相同URL的多个名称空间(例如,如果你有两个xmlns:h="https://www.namespaces.com/namespaceOne"在不同的孩子身上),如果你想这样做,只需保留一个已添加到根元素的名称空间列表,

...