我正在尝试对导出的一组XML文件执行XSL 1.0转换,并在其他地方转换具有重复节点的文件 - 我能够删除相同的重复节点,但不能删除具有不同的值/属性。 。 我想要实现的只是保留第二组错误节点。感谢任何有助于理解我出错的地方!
一组XML文件包含如下数据:
<row xmlns="http://www.example.com/abc/xyz" xmlns:dg="http://www.example.com/abc/def" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<data>
<status>Y</status>
<product>48530</product>
<id>12312343</id>
<error xmlns="">true</error>
<errorReason xmlns="">Detailed error message</errorReason>
<error xmlns="">true</error>
<errorReason xmlns="">Detailed error message</errorReason>
</data>
</row>
使用以下XSL时,将删除重复项:
<xsl:stylesheet version="1.0" exclude-result-prefixes="xsi d dg"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:d="http://www.example.com/abc/xyz"
xmlns:dg="http://www.example.com/abc/def" >
<xsl:output omit-xml-declaration="yes" method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="comment()"/>
<!-- Drill down into the export XML and extract only the main table row data -->
<xsl:template match="d:row">
<xsl:apply-templates select="d:data"/>
</xsl:template>
<xsl:template match="error[preceding::error]"/>
<xsl:template match="errorReason[preceding::errorReason]"/>
</xsl:stylesheet>
但是,当我为一组XML文件尝试相同的XSL时,如下所示:
<row xmlns="http://www.example.com/abc/xyz" xmlns:dg="http://www.example.com/abc/def" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<data>
<status>Y</status>
<product>130160072014</product>
<dob>11/11/1911</dob>
<id>12312312</id>
<error>false</error>
<errorReason />
<error xmlns="">true</error>
<errorReason xmlns="">Detailed error message</errorReason>
</data>
</row>
什么都没发生。
我怀疑空 xmlns 可能是原因,但我不太确定。
答案 0 :(得分:1)
这是因为命名空间。 xmlns
是名称空间声明。在您的第一个XML中,error
和errorreason
元素都声明了xmlns=""
,这意味着它们都没有名称空间。
但是,在第二个XML中,您可以执行此操作:
<error>false</error>
<errorReason />
<error xmlns="">true</error>
<errorReason xmlns="">Detailed error message</errorReason>
第一个error
和errorReason
没有明确的xmlns
,这意味着它们位于row
元素<上定义的默认命名空间中/ p>
<row xmlns="http://www.example.com/abc/xyz"
该声明不仅适用于row
元素,也适用于其后代,除非被覆盖。
这意味着第一个error
和errorReason
与另外两个名称空间不同(实际上并不在命名空间中),因此它们实际上是不同的。它们与您的XSLT模板不匹配,因为模板仅匹配无命名空间中的元素。
您还没有说过要保留哪一对元素。命名空间中的那些,或没有命名空间的那些。但是,如果你真的想要删除“重复”而不管命名空间如何,你可以使用这两个模板,它们只是完全忽略命名空间(因此将保留第一个元素,在你的例子中位于命名空间中)。 p>
<xsl:template match="*[local-name() = 'error'][preceding::*[local-name() = 'error']]"/>
<xsl:template match="*[local-name() = 'errorReason'][preceding::*[local-name() = 'errorReason']]"/>