如何将 XML 命名空间提升到根元素



如果我有一个带有命名空间的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</h:name>
<h:width>80</h:width>
<h:length>120</h:length>
</h:table>
</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</h1:name>
<h1:width>80</h1:width>
<h1:length>120</h1:length>
</h1:table>
</root>

有没有办法做到这一点?理想情况下,自动解析冲突的命名空间前缀,如上例所示。我还没有承诺使用Linq to XMLSystem.Xml,所以两者都有可能。

有一个主要的制约因素:由于我所处的环境,我不能写课。我可以编写函数,但没有新的类定义。

事实证明这很简单:

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"(。对于我们找到的每个元素,我们在根元素上放置一个具有相同 URL 的命名空间属性,然后删除该属性。

演示。

请注意,如果您有多个具有相同 URL 的命名空间(例如,如果您在不同的子级上有两个大量xmlns:h="https://www.namespaces.com/namespaceOne"(,这会做一些奇怪的事情:它会在具有相同 URL 的根元素上放置多个xmlns声明,但所有元素都使用最后一个这样的命名空间。如果要避免这种情况,只需保留已添加到根元素的命名空间列表即可。

相关内容

  • 没有找到相关文章

最新更新