删除包含 xmlns 属性的 XML 元素

Remove an XML element containing an xmlns attribute

我想使用 XSLT 从 XML 文件中删除名为 "searchBookResponse" 的元素(包装器 - 不是后代)。

当 "searchBookResponse" 元素没有属性或没有 "xmlns" 属性时,我的 XSLT 代码工作正常。 但是,有了这些 xmlns 属性,它就不再起作用了。

这是输入XML文档:

<?xml version="1.0" encoding="utf-8"?>
<books>
  <searchBookResponse xmlns="urn:example.com" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <book>
      <author>Tom</author>
      <title>Test</title>
    </book>
    <book>
      <author>David</author>
      <title>Test two</title>
    </book>
  </searchBookResponse>
  <book>
    <author>Anas</author>
    <title>Test two</title>
  </book>
  <book>
    <author>Jim</author>
    <title>Test two</title>
  </book>
</books>

这是 XSL 样式表:

<?xml version="1.0" encoding="iso-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="@xmlns" />


  <xsl:template match="searchBookResponse">
      <xsl:apply-templates select="node()" />
  </xsl:template>
</xsl:stylesheet>

应用后,输出 XML 文件与输入 XML 文件相同。我必须先应用一些字符串模式匹配来删除 xmlns 属性,然后再删除实际元素吗? 我想实现这样的目标:

<?xml version="1.0" encoding="utf-8"?>
    <books>
        <book>
          <author>Tom</author>
          <title>Test</title>
        </book>
        <book>
          <author>David</author>
          <title>Test two</title>
        </book>
      <book>
        <author>Anas</author>
        <title>Test two</title>
      </book>
      <book>
        <author>Jim</author>
        <title>Test two</title>
      </book>
    </books>

-------------------------------------------- --------------------

好的,蒂姆和迈克尔为我提供了正确答案。但是现在我对原文档进行了扩展如下:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <LibrarySearchResponse xmlns="urn:soft.librarysearch" xmlns:tns="urn:soft.librarysearch">
      <tns:query/>
      <tns:books>
        <searchBooksResponse xmlns="urn:soft.vub.ac.be/" xmlns:xsd="http://www.w3.org/2001/
XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <tns:book>
            <tns:author>Robert Ludlum</tns:author>
            <tns:isbn>95248457</tns:isbn>
            <tns:publicationDate>2004-01-01T00:00:00Z</tns:publicationDate>
            <tns:publisher>Orion</tns:publisher>
            <tns:title>The Bourne Identity</tns:title>
          </tns:book>
          <tns:book>
            <tns:author>Douglas Adams</tns:author>
            <tns:isbn>345453743</tns:isbn>
            <tns:publicationDate>2002-01-01T00:00:00Z</tns:publicationDate>
            <tns:publisher>Del Rey</tns:publisher>
            <tns:title>The Ultimate Hitchhiker's Guide to the Galaxy</tns:title>
          </tns:book>
          <tns:book>
            <tns:author>William Sleator</tns:author>
            <tns:isbn>810993562</tns:isbn>
            <tns:publicationDate>2008-01-01T00:00:00Z</tns:publicationDate>
            <tns:publisher>Amulet Books</tns:publisher>
            <tns:title>Test</tns:title>
          </tns:book>
          <tns:book>
            <tns:author>Jordan Belfort</tns:author>
            <tns:isbn>606259090</tns:isbn>
            <tns:publicationDate>2008-01-01T00:00:00Z</tns:publicationDate>
            <tns:publisher>Hodder Paperback</tns:publisher>
            <tns:title>The Wolf of Wall Street</tns:title>
          </tns:book>
        </searchBooksResponse>
        <tns:book xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://library.be"
        xmlns:nl="http://library.be" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <tns:author>James, E. L.</tns:author>
          <tns:isbn>0345803485</tns:isbn>
          <tns:publicationDate>3914-01-10T23:00:00.000Z</tns:publicationDate>
          <tns:publisher>Vintage Books</tns:publisher>
          <tns:title>50 Shades of Grey</tns:title>
        </tns:book>
        <tns:book xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://library.be"
        xmlns:nl="http://library.be" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <tns:author>James Dashner</tns:author>
          <tns:isbn>0385388896</tns:isbn>
          <tns:publicationDate>3914-04-20T22:00:00.000Z</tns:publicationDate>
          <tns:publisher>The Maze Runner Series</tns:publisher>
          <tns:title>Test</tns:title>
        </tns:book>
        <tns:book xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://library.be"
        xmlns:nl="http://library.be" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <tns:author>William Sleator</tns:author>
          <tns:isbn>0810993562</tns:isbn>
          <tns:publicationDate>3908-03-31T22:00:00.000Z</tns:publicationDate>
          <tns:publisher>Amulet Books</tns:publisher>
          <tns:title>Test</tns:title>
        </tns:book>
        <tns:book xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://library.be"
        xmlns:nl="http://library.be" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <tns:author>Douglas Adams</tns:author>
          <tns:isbn>0345453743</tns:isbn>
          <tns:publicationDate>3902-05-29T22:00:00.000Z</tns:publicationDate>
          <tns:publisher>Del Rey</tns:publisher>
          <tns:title>The Ultimate Hitchhiker's Guide to the Galaxy</tns:title>
        </tns:book>
        <tns:book xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://library.be"
        xmlns:nl="http://library.be" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <tns:author>Michalewicz, Zbigniew Fogel, David B.</tns:author>
          <tns:isbn>9783642061349</tns:isbn>
          <tns:publicationDate>3912-10-31T23:00:00.000Z</tns:publicationDate>
          <tns:publisher>Del Rey</tns:publisher>
          <tns:title>How to Solve It: Modern Heuristics</tns:title>
        </tns:book>
      </tns:books>
    </LibrarySearchResponse>
  </soapenv:Body>
</soapenv:Envelope>

我仍然想删除 searchBookResponse 元素(包装器),但出现以下错误:"The source document is in namespace http://schemas.xmlsoap.org/soap/envelope/, but none of the template rules match elements in this namespace."

但是,当我这样缩短文档时:

<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
  <soapenv:Body>
    <LibrarySearchResponse xmlns="urn:soft.librarysearch" xmlns:tns="urn:soft.librarysearch">
      <books>
        <searchBookResponse xmlns="urn:soft.vub.ac.be" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <book>
            <author>Tom</author>
            <title>Test one</title>
          </book>
          <book>
            <author>David</author>
            <title>Test two</title>
          </book>
        </searchBookResponse>
        <book xmlns="http://library.be" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:nl="http://library.be" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
          <author>James, E. L.</author>
          <title>50 Shades of Grey</title>
        </book>
      </books>
    </LibrarySearchResponse>
  </soapenv:Body>
</soapenv:Envelope>

searchBookResponse 元素 - 包装器已被删除,不显示任何错误消息,输出如下:

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <LibrarySearchResponse xmlns="urn:soft.librarysearch" xmlns:tns="urn:soft.librarysearch">
         <books>
            <book xmlns="">
               <author>Tom</author>
               <title>Test one</title>
            </book>
            <book xmlns="">
               <author>David</author>
               <title>Test two</title>
            </book>
            <book xmlns="http://library.be"
                  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
                  xmlns:nl="http://library.be"
                  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
               <author>James, E. L.</author>
               <title>50 Shades of Grey</title>
            </book>
         </books>
      </LibrarySearchResponse>
   </soapenv:Body>
</soapenv:Envelope>

使用此样式表:

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="urn:soft.vub.ac.be">

  <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
  <xsl:strip-space elements="*"/>

  <!-- identity transform -->
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="ns1:searchBookResponse" >
    <xsl:apply-templates select="*" mode="remove-namespace"/>
  </xsl:template>

  <xsl:template match="*" mode="remove-namespace">
    <xsl:element name="{local-name()}">
      <xsl:copy-of select="@*"/>
      <xsl:apply-templates select="@*|node()" mode="remove-namespace"/>
    </xsl:element>
  </xsl:template>

</xsl:stylesheet>

我必须声明更多名称空间并匹配它们中的每一个吗?为什么缩短的版本可以正常工作而原始的完整版本却不行?

提前致谢!

xmlns 不是属性。它是一个命名空间声明。在您的情况下,它是默认命名空间。这意味着 searchBookResponse 元素及其下面的所有节点都属于该命名空间,并且此类元素不同于不同命名空间中的同名元素,或者根本没有命名空间。

要解决您的问题,您需要在 XSLT 中使用前缀声明名称空间,然后使用该前缀来标识元素。

试试这个 XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  xmlns:e="urn:example.com" exclude-result-prefixes="e">
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <xsl:template match="e:searchBookResponse">
      <xsl:apply-templates select="node()" />
  </xsl:template>
</xsl:stylesheet>

请注意两个 book 元素如何也是原始 XML 中命名空间的一部分,因此也将成为输出中命名空间的一部分。如果您想从输出中删除命名空间的所有痕迹 XML,请尝试将此模板也添加到 XSLT

<xsl:template match="e:*">
    <xsl:element name="{local-name()}">
         <xsl:apply-templates select="node() | @*" />
    </xsl:element>
</xsl:template>

如果您想深入了解命名空间,请尝试这篇文章作为入门文章:http://www.xml.com/pub/a/1999/01/namespaces.html。真的很值得一读,因为他们确实在第一次见面时就抓住了很多人。

如果要删除 <searchBookResponse xmlns="urn:example.com"> 包装器并将其中包含的书籍添加到其余书籍中,则还必须从这些书籍中删除命名空间。

否则你会得到两种书:<book><book xmlns="urn:example.com">。这两个不是一回事。

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ns1="urn:example.com">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="ns1:searchBookResponse" >
    <xsl:apply-templates select="*" mode="remove-namespace"/>
</xsl:template>

<xsl:template match="*" mode="remove-namespace">
    <xsl:element name="{local-name()}">
        <xsl:copy-of select="@*"/>
        <xsl:apply-templates select="@*|node()" mode="remove-namespace"/>
    </xsl:element>
</xsl:template>

</xsl:stylesheet>

结果:

<?xml version="1.0" encoding="UTF-8"?>
<books>
   <book>
      <author>Tom</author>
      <title>Test</title>
   </book>
   <book>
      <author>David</author>
      <title>Test two</title>
   </book>
   <book>
      <author>Anas</author>
      <title>Test two</title>
   </book>
   <book>
      <author>Jim</author>
      <title>Test two</title>
   </book>
</books>