2015-11-15 59 views
0

我试图对导出的一组XML文件执行XSL 1.0转换并将其转换到其他具有重复节点的地方 - 我可以删除相同重复节点,但不是那些具有不同价值/属性的人。我试图实现的是仅保留第二组错误节点。任何帮助,了解我要去哪里错了赞赏!使用XSLT删除具有不同值/属性的重复节点

一套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> 

然而,当我尝试同样的XSL一组的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>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也许是原因,但我不太确定。

+1

请张贴最小但完整的XML和XSLT片段,以便我们重现该问题。在你没有显示的祖先或父元素上是否有任何名称空间声明? XSLT的其余部分是做什么的? –

+0

在测试http://www.utilities-online.info/xsltransformation/?save=165d0629-fc24-4ac2-9c30-3526d3520b57-xsltransformation#.VkjZ2-KAl40重复的'error'和'errorReason'元素被删除使用您的两个模板加上身份转换模板的XSLT代码。 –

+0

你想要的结果是什么?你想保留哪个错误节点?第一个按顺序? – Parfait

回答

1

这是因为命名空间。 xmlns是一个名称空间声明。在您的第一个XML中,errorerrorreason元素都声明为xmlns="",这意味着它们都不在名称空间中。

然而,在你的第二个XML你这样做:

<error>false</error> 
<errorReason /> 
<error xmlns="">true</error> 
<errorReason xmlns="">Detailed error message</errorReason> 

第一errorerrorReason都没有一个明确的xmlns上,这意味着它们在其中的row定义的默认命名空间元素

<row xmlns="http://www.example.com/abc/xyz" 

的声明适用于不只是row元素,但它的后代,除非overridde。

这意味着第一个errorerrorReason与另外两个名称空间(它们实际上不在名称空间中)处于不同的名称空间中,因此它们实际上有所不同。它们与您的XSLT模板不匹配,因为模板只匹配没有名称空间中的元素。

你还没有说你想保留哪对元素。那些在命名空间中,或没有的。但是,如果确实想删除“重复项”而不考虑名称空间,则可以使用这两个模板,它们完全忽略了名称空间(因此将保留第一个元素,它们位于您的案例中的名称空间中)。

<xsl:template match="*[local-name() = 'error'][preceding::*[local-name() = 'error']]"/> 
<xsl:template match="*[local-name() = 'errorReason'][preceding::*[local-name() = 'errorReason']]"/> 
+0

谢谢蒂姆。你的回答非常有帮助。一旦我添加到名称空间参考中,模板就可以工作。 – smkndblvr