我经常遇到 XML,其中多次定义相同的命名空间,而不是仅在需要它的元素的父元素处定义。
是否有一个简单的方法/工具来提取 XML 中的所有命名空间定义并将每个定义重新定位到一个节点,以便每个命名空间仅定义一次?最好还有一个选项,让所有节点都以其名称空间为前缀(而不是使用某个父节点的默认名称空间)。我发现这会产生更多人类可读的 XML。
举个例子,如何自动翻译这个
<m:Albums xmlns:m="http://www.example.com/music">
<m:Album xmlns:m="http://www.example.com/music">
<m:Artist xmlns:m="http://www.example.com/music">
<c:Name xmlns:c="http://www.example.com/common">
Sting
</c:Name>
</m:Artist>
<m:Title>
Mercury Falling
</m:Title>
</m:Album>
<Album xmlns="http://www.example.com/music">
<Artist>
<c:Name xmlns:c="http://www.example.com/common">
Maria Mena
</c:Name>
</Artist>
<Title xmlns="http://www.example.com/music">
Weapon in Mind
</Title>
</Album>
</m:Albums>
进入这个?
<m:Albums xmlns:m="http://www.example.com/music" xmlns:c="http://www.example.com/common">
<m:Album>
<m:Artist>
<c:Name>
Sting
</c:Name>
</m:Artist>
<m:Title>
Mercury Falling
</m:Title>
</m:Album>
<m:Album>
<m:Artist>
<c:Name>
Maria Mena
</c:Name>
</m:Artist>
<m:Title>
Weapon in Mind
</m:Title>
</m:Album>
</m:Albums>
作为我自己问题的部分答案,我发现 unix 命令
xmllint --nsclean
部分解决了问题,但并没有消除所有重复的命名空间。当应用于问题中的示例 XML 时,它会产生以下结果。
<m:Albums xmlns:m="http://www.example.com/music">
<m:Album>
<m:Artist>
<c:Name xmlns:c="http://www.example.com/common">
Sting
</c:Name>
</m:Artist>
<m:Title>
Mercury Falling
</m:Title>
</m:Album>
<Album xmlns="http://www.example.com/music">
<Artist>
<c:Name xmlns:c="http://www.example.com/common">
Maria Mena
</c:Name>
</Artist>
<Title>
Weapon in Mind
</Title>
</Album>
</m:Albums>
这消除了父节点中已声明的名称空间。但是,它不会将重复的命名空间声明拉到公共父级(例如
c:Name
节点),也不会通过将受影响的节点转换为使用等效的非默认命名空间(例如 Album
)来删除重复的默认命名空间。默认命名空间中的节点及其子节点)。
仍然希望有一个解决方案,可以在
xmllint
失败的情况下删除重复的命名空间。
作为对我自己的问题的更好答案,我偶然发现了这个外部 XSLT 转换(编辑:XSLT 2.0 版本),它正是我想要的。
使用带有 Saxon 的 XSLT 转换问题的输入 XML 的结果:
<m:Albums xmlns:m="http://www.example.com/music" xmlns:c="http://www.example.com/common">
<m:Album>
<m:Artist>
<c:Name>
Sting
</c:Name>
</m:Artist>
<m:Title>
Mercury Falling
</m:Title>
</m:Album>
<m:Album>
<m:Artist>
<c:Name>
Maria Mena
</c:Name>
</m:Artist>
<m:Title>
Weapon in Mind
</m:Title>
</m:Album>
</m:Albums>