我想删除名为" 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>
我必须声明更多名称空间并匹配其中的每一个吗?为什么缩短版本工作正常,原始的完整版本没有?
提前致谢!
答案 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>