2012-04-21 32 views
1

這是我的xml:如何在循環期間更新或追加XML節點?

<rootNode> 
    <sample> 
     <DO type="TD" name="ABC" ref="1"> 
      <text>text</text> 
     </DO> 
     <DO type="CI" name="DEF" ref="2"> 
      <text></text> 
     </DO> 
     <DO type="PL" name="GHI" ref="3"> 
      <text>text</text> 
     </DO> 
     <DO type="AB" name="JKL" ref="4"> 
      <text>text</text> 
     </DO> 
    </sample> 
    <Docs> 
     <Document> 
      <type>TD</type> 
      <name>ABC</name> 
      <ref>1</ref> 
      <text>sample text</text> 
     </Document> 
     <Document> 
      <type>CI</type> 
      <name>DEF</name> 
      <ref>2</ref> 
      <text>sample text</text> 
     </Document> 
     <Document> 
      <type>PL</type> 
      <name>GHI</name> 
      <ref>3</ref> 
      <text>sample text</text> 
     </Document> 
     <Document> 
      <type>AB</type> 
      <name>JKL</name> 
      <ref>4</ref> 
      <text>sample text</text> 
     </Document> 
     <Document> 
      <type>CD</type> 
      <name>JKL</name> 
      <ref>5</ref> 
      <text>sample text</text> 
     </Document> 
    </Docs> 
</rootNode> 

如果任何樣品/ DO的類型,名稱和參考文獻與任何文檔/文件類型,名稱和ref的匹配。使用文檔/文本更新樣本/ DO /文本。否則(如果任何樣品/類型,名稱,參考文獻與文檔/文檔類型,名稱,參考文獻不匹配),則應附加整個文檔/文檔。

注意:樣品/ DO的順序不應改變。我的意思是如果任何文件有任何匹配相同應更新。否則應該追加新的。

+0

你使用純xpath還是其他語言 – 2012-04-21 05:58:49

+0

需要使用xpath(1.0或2.0)實現它 – cbx 2012-04-21 06:11:04

+0

@bose:這是什麼意思:「否則(如果任何樣本/ Do的類型,name,ref與Docs/Document類型,name,ref不匹配),那麼應附加從Docs/Document開始的整個Document。「 *應該附加哪個*文檔/文檔?請解釋。 – 2012-04-21 16:33:53

回答

0

據我所知,你不能通過使用純xpath來更新文檔,xpath的思想主要用於根據特定的比較從文檔中選擇特定的節點。實現這一點的唯一好方法是需要使用另一種語言,您可以使用xpath和更新元素,這可能類似於php Simplexml。閱讀不同的來源許多人建議不同的建議,但它主要用xquery解決這裏有幾個鏈接。

http://www.w3.org/XML/Query/

http://www.w3.org/TR/xquery-update-10-use-cases/

http://www.w3.org/TR/xquery-update-10/

1

如果使用XSLT來複制和轉換文檔,你可以利用兩個XSL:關鍵** s到查找**文件元素和SO元素。在這種情況下,你需要重點

<xsl:key name="docs" match="Document" use="concat(type, '|', name, '|', ref)"/> 
<xsl:key name="samples" match="DO" use="concat(@type, '|', @name, '|', @ref)"/> 

一種化合物可以首先匹配具有像這樣

<xsl:template match="DO[key('docs', concat(@type, '|', @name, '|', @ref))]"> 

匹配的文檔元素(如果所有SO元素被保證SO元素有一個匹配的**文檔元素,這可以簡化爲<xsl:template match="DO" >

在此模板中那麼您可以簡單地將代碼添加到此模板中,以便從密鑰中複製元素中的文本元素。

要匹配文檔元素沒有相應的SO元素,你可以這樣做:

<xsl:apply-templates 
    select="/rootNode/Docs/Document[not(key('samples', concat(type, '|', name, '|', ref)))]" 
    mode="Document"/> 

而對於匹配的模板,你可以將其轉換爲一個SO元素。

以下是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 
    <xsl:key name="docs" match="Document" use="concat(type, '|', name, '|', ref)"/> 
    <xsl:key name="samples" match="DO" use="concat(@type, '|', @name, '|', @ref)"/> 


    <xsl:template match="DO[key('docs', concat(@type, '|', @name, '|', @ref))]"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*"/> 
      <xsl:copy-of select="key('docs', concat(@type, '|', @name, '|', @ref))/text"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="sample"> 
     <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     <xsl:apply-templates select="/rootNode/Docs/Document[not(key('samples', concat(type, '|', name, '|', ref)))]" mode="Document"/> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="Document" mode="Document"> 
     <DO type="{type}" name="{name}" ref="{ref}"> 
      <xsl:copy-of select="text" /> 
     </DO> 
    </xsl:template> 

    <xsl:template match="Docs" /> 

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

以下是輸出

<rootNode> 
    <sample> 
     <DO type="TD" name="ABC" ref="1"> 
     <text>sample text</text> 
     </DO> 
     <DO type="CI" name="DEF" ref="2"> 
     <text>sample text</text> 
     </DO> 
     <DO type="PL" name="GHI" ref="3"> 
     <text>sample text</text> 
     </DO> 
     <DO type="AB" name="JKL" ref="4"> 
     <text>sample text</text> 
     </DO> 
     <DO type="CD" name="JKL" ref="5"> 
     <text>sample text</text> 
     </DO> 
    </sample> 
</rootNode> 

請注意我排除在輸出文檔節點,但是從XSLT如果只是刪除相關行你想保留它們。

+0

發誓:-) 非常感謝。這正是我正在尋找的。 – cbx 2012-04-21 13:33:13