使用 xmlstarlet 从 xml 中删除所有命名空间属性

使用 xmlstarlet 从 xml 中删除所有命名空间属性

我想从以下 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

  1. 如何使用 XSLT 删除 XML 文件中的名称空间及其前缀?- IBM
  2. 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 文档结构中的所有节点,并删除所有找到的属性xmlnsxmlns: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

相关内容