![使用 xmlstarlet 从 xml 中删除所有命名空间属性](https://linux22.com/image/211912/%E4%BD%BF%E7%94%A8%20xmlstarlet%20%E4%BB%8E%20xml%20%E4%B8%AD%E5%88%A0%E9%99%A4%E6%89%80%E6%9C%89%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4%E5%B1%9E%E6%80%A7.png)
我想从以下 XML 中删除所有命名空间属性。
<md:EntityDescriptor xmlns="urn:_" xmlns:md="_"></md:EntityDescriptor>
我尝试xmlns
使用以下命令删除它,但无论如何都不会更改输入。
xmlstarlet ed \
-N n="urn:oasis:names:tc:SAML:2.0:metadata" \
-d '/md:EntityDescriptor/@*[n:name()="xmlns"]' \
<<< '<md:EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata" xmlns:md="_"></md:EntityDescriptor>' \
> ttt.xml
预期输出:
<md:EntityDescriptor></md:EntityDescriptor>
答案1
我找到了几个 XSLT 解决方案来执行此操作,这两个解决方案都可以方便地使用以下方法进行处理xmlstarlet
:
- 如何使用 XSLT 删除 XML 文件中的名称空间及其前缀?- IBM
- XSLT:从元素中删除名称空间前缀- 堆栈溢出
在下面的工作示例中,我使用了 IBM 代码并将其保存到文件中xslt_ibm
:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<!-- https://www.ibm.com/support/pages/how-remove-namespace-and-its-prefixes-xml-file-using-xslt -->
<xsl:output method="xml" indent="yes"/>
<xsl:template match="/|comment()|processing-instruction()">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:element name="{local-name()}">
<xsl:apply-templates select="@*|node()"/>
</xsl:element>
</xsl:template>
<xsl:template match="@*">
<xsl:attribute name="{local-name()}">
<xsl:value-of select="."/>
</xsl:attribute>
</xsl:template>
</xsl:stylesheet>
如果您考虑将 XML 文件保存在文件中,file.xml
那么此命令将重命名其命名空间之外的每个元素和属性:
xmlstarlet transform xslt_ibm file.xml
输入 (file.xml
)
<md:EntityDescriptor xmlns="urn:_" xmlns:md="_"></md:EntityDescriptor>
输出
<?xml version="1.0"?>
<EntityDescriptor/>
答案2
使用 Andrey Kislyuk 的xq
,一个 XML 解析包装器jq
(与yq
):
xq -x 'walk(del( .["@xmlns"]?, .["@xmlns:md"]? ))' file
这将遍历 XML 文档结构中的所有节点,并删除所有找到的属性xmlns
。xmlns:md
给定一些输入文档,
<?xml version="1.0"?>
<root test="val">
<md:EntityDescriptor xmlns="urn:_" xmlns:md="_"/>
</root>
...这会输出
<root test="val">
<md:EntityDescriptor></md:EntityDescriptor>
</root>
--in-place
您可以使用或选项进行就地编辑-i
。