2012-07-22 64 views
-1

我有一個XML我想將其轉換爲xslt。 輸入如下所示。XSL - 刪除包含特定條件的父節點

<xmeml> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>tuvw</Unit3> 
    </Test> 
    <Test> 
     <Unit>bcd</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
    <Test> 
     <Unit>cde</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
    <Test> 
     <Unit>def</Unit> 
     <Unit2>4567</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>uvwx</Unit3> 
    </Test> 
    <Test> 
     <Unit>efg</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
</xmeml> 

輸出應該看起來像這樣。

<xmeml> 
<Doc> 
    <Test> 
     <Unit>bcd</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
    <Test> 
     <Unit>cde</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
    <Test> 
     <Unit>def</Unit> 
     <Unit2>4567</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
<Doc> 
    <Test> 
     <Unit>efg</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
    </Test> 
</Doc> 
</xmeml> 

我想刪除任何符合以下條件的測試節點。 - Unit3子節點以tuv或uvw開頭。 - AND單元和單元2的值都發現在另一個測試節點中重複/複製

在此先感謝您的幫助。

+0

user1540142,我更新了我的答案。這是你想要的嗎? – 2012-07-22 06:47:10

+0

嗨,你在這裏看起來很新鮮,所以我想我會解釋爲什麼這是被低估的:向我們表明,在向我們尋求幫助之前,你已經有了一個好主意。例如:你有什麼嘗試過自己?它對你有什麼問題?如果您可以將此添加到您的問題中,我們將不僅能夠更好地指出您的錯誤,我們會更好地幫助您:) – 2012-07-24 08:30:32

+0

謝謝Taryn,將來會做。這是一個巨大的信息和人員資源。我很快就學會了行話和正確的協議。 – user1540142 2012-07-24 12:15:14

回答

1

這個怎麼樣的調整Dimitre的解決方案......

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:key name="kTest" match="Test" use="concat(Unit, '+', Unit2)"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
    "Test[key('kTest', concat(Unit, '+', Unit2))[2]] 
    [starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')]"/> 
</xsl:stylesheet> 

據我瞭解,改造的規則是:

  1. 將所有節點作爲是,除特別說明外以下。
  2. 排除所有測試節點具有以下屬性:

2.1存在另一個測試節點(稱之爲測試(其他))的文件,使得:

(Test(reference)/Unit = Test(other)/Unit) AND 
    (Test(reference)/Unit2 = Test(other)/Unit2) 

2.2 UNIT3孩子的參考測試節點以tuv或uvw開頭

此輸出與OP發佈的完全相同。有趣的是,如果我已經正確地理解了這個問題,Dimitre最近剛剛提供了一個解決方案,幾乎和你在這裏的問題一樣,這就是XSL comparison of nodes。再說一遍,如果我已經正確地理解了你的問題,這個標題就會讓人產生誤解。 「刪除重複」通常意味着去重複,如(1,2,2,3) - >(1,2,3);而像(1,2,2,3) - >(1,3)這樣的要求通常被描述爲「選擇唯一節點/值」。

+0

是的,它是一個棘手的描述。基本上我想刪除所有測試節點,其中單元3的值以tuv或uvw開頭。作爲一個檢查,但我還需要看看是否有任何重複條目由Unit和Unit2值定義。所以我認爲真正的問題是,如果Unit3以tuv或uvw開頭,並且它的Unit和Unit2值在另一個Test節點中重複,則將其刪除。那有意義嗎。 – user1540142 2012-07-22 11:54:08

+0

看來你的工作是完美的。謝謝你親愛的澳大利亞;)謝謝你,Dimite因爲成爲病人。 – user1540142 2012-07-22 12:05:28

+0

@ user1540142:問題仍然沒有編輯,相當混亂。我重申,您必須編輯問題並明確表達清楚。對於將來的問題,請特別注意提出明確而明確的問題,以免浪費讀者和您自己的時間。每當有人提出含糊不清的問題時,他們只是在描述他們提出的問題 - 而不是他們認爲的問題。 – 2012-07-22 15:07:08

1

該轉化(Muenchian分組的 - 基於):

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:key name="kTest" 
    match="Test[starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')]" 
      use="concat(Unit, '+', Unit2)"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
    "Test[starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')] 
    [not(generate-id() 
    = 
    generate-id(key('kTest', concat(Unit, '+', Unit2))[last()]))]"/> 
</xsl:stylesheet> 

當所提供的XML文檔施加:

<xmeml> 
    <Doc> 
     <Test> 
      <Unit>abc</Unit> 
      <Unit2>1234</Unit2> 
      <Unit3>tuvw</Unit3> 
     </Test> 
     <Test> 
      <Unit>bcd</Unit> 
      <Unit2>2345</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
      <Unit>abc</Unit> 
      <Unit2>3456</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
      <Unit>cde</Unit> 
      <Unit2>3456</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
      <Unit>abc</Unit> 
      <Unit2>1234</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
      <Unit>def</Unit> 
      <Unit2>4567</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
      <Unit>abc</Unit> 
      <Unit2>1234</Unit2> 
      <Unit3>uvwx</Unit3> 
     </Test> 
     <Test> 
      <Unit>efg</Unit> 
      <Unit2>2345</Unit2> 
      <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
</xmeml> 

產生正確的結果(實現所有要求) :

<xmeml> 
    <Doc> 
     <Test> 
     <Unit>bcd</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>abc</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
     <Unit>cde</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
     <Unit>def</Unit> 
     <Unit2>4567</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>uvwx</Unit3> 
     </Test> 
     <Test> 
     <Unit>efg</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
</xmeml> 

更新

的OP有自己的問題,這是不明確的,並沒有精確定義的解釋。

有了相當大的猜測,這裏是他可能想...:

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 
<xsl:key name="kTest" 
    match="Test" use="concat(Unit, '+', Unit2)"/> 

<xsl:template match="node()|@*"> 
    <xsl:copy> 
    <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match= 
    "Test[starts-with(Unit3, 'tuv') or starts-with(Unit3, 'uvw')] 
    [not(generate-id() 
    = 
    generate-id(key('kTest', concat(Unit, '+', Unit2)) 
            [not(position()=1)]) 
       )]"/> 
</xsl:stylesheet> 

當這種轉變是在所提供的XML文檔(以上)應用,現在的結果與OP認爲什麼相同是想要的結果

<xmeml> 
    <Doc> 
     <Test> 
     <Unit>bcd</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>abc</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
     <Unit>cde</Unit> 
     <Unit2>3456</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>abc</Unit> 
     <Unit2>1234</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
     <Test> 
     <Unit>def</Unit> 
     <Unit2>4567</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
    <Doc> 
     <Test> 
     <Unit>efg</Unit> 
     <Unit2>2345</Unit2> 
     <Unit3>wxyz</Unit3> 
     </Test> 
    </Doc> 
</xmeml> 
+0

謝謝Dimitre,:)作品一種享受! – user1540142 2012-07-22 03:30:02

+0

嗨Dimitre,實際上它看起來像沒有從底部拾取後者的候選人,第二個測試節點。匹配單元和Unit2值和Unit3以uvw開頭。 – user1540142 2012-07-22 04:08:00

+0

@ user1540142:我不明白你在說什麼。你能解釋一下嗎?轉型嚴格執行所有要求。 – 2012-07-22 04:10:57