删除包含xmlns属性的XML元素

时间:2015-04-19 20:30:08

标签: xml xslt namespaces xml-namespaces

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

当" searchBookResponse" element没有属性或者没有" 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>

我必须声明更多名称空间并匹配其中的每一个吗?为什么缩短版本工作正常,原始的完整版本没有?

提前致谢!

2 个答案:

答案 0 :(得分:3)

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。真的值得读一读,因为当他们第一次遇到时,他们确实会发现很多人。

答案 1 :(得分:2)

如果要删除<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>