2015-11-15 92 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