2011-05-06 89 views
1

這裏是問題,我有一個不完整的文檔(docA),並且想要在由某個xpath字符串(在doc元素列表中)定義的某個特定位置插入一些xml元素到獲得完整的文檔(docB)。使用xpath在xml文檔中插入一個元素

所以基本上,鑑於該文件的DOCA:

<document> 
    <information type="person"> 
     <id>string</id> 
     <customer> 
      <customerID>abc</customerID> 
      <externalID>2</externalID> 
      <person> 
       <gender>M</gender> 
       <firstName>John</firstName> 
       <!-- here should be a middle name --> 
       <lastName>Doe</lastName> 
       <birthdate>2011-05-05</birthdate> 
      </person> 
      <!-- more elements... --> 
     </customer> 
     <!-- more elements... --> 
    </information > 
</document> 

和元素列表:

<newElementSet> 
    <element> 
     <name>Middle Name</name> 
     <path>/document/information/customer/person/middleName</path> 
     <value>Fitzgerald</value> 
    </element> 
    <!-- some more element could go there --> 
</newElementSet> 

輸出文檔應該是:

<document> 
    <information type="private"> 
     <id>string</id> 
     <customer> 
      <customerID>abc</customerID> 
      <externalID>2</externalID> 
      <person> 
       <gender>M</gender> 
       <firstName>John</firstName> 
       <middleName>Fitzgerald</middleName> 
       <lastName>Doe</lastName> 
       <birthdate>2011-05-05</birthdate> 
      </person> 
       <!-- more elements... --> 
     </customer> 
     <!-- more elements... --> 
    </information > 
</document> 

任何方式,這可能在做XSLT?我試過使用Xquery,但它似乎不可能(不能使用Xquery更新,因爲它尚不支持)。

編輯:我只想確切地說,這只是對問題的簡單介紹。在現實中,我們有更多的元素添加有值實際上會從用戶輸入取...

+0

您的XPath不會告訴您的新元素應該在''元素的哪個位置。有關係嗎? – 2011-05-06 09:13:44

+0

在某些情況下,它實際上可能會在我們的模式中定義。這是否意味着我們必須修改我們的xpath定義或添加更多信息? – florent 2011-05-06 09:24:23

+0

提供''描述不包含任何唯一的信息來標識您需要更新哪個'客戶/人'。或者你想給所有人添加' Fitzgerald'? – 2011-05-06 12:40:47

回答

1

這可以很容易地完成,你只需要改變「元素列表」文件一點點 - - 這個XML文檔

<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:template match="node()|@*" name="identity"> 
    <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="person/firstName"> 
    <xsl:call-template name="identity"/> 
    <middleName>Fitzgerald</middleName> 
</xsl:template> 
</xsl:stylesheet> 

然後,只需將此轉變到提供源XML文檔

<document> 
    <information type="person"> 
     <id>string</id> 
     <customer> 
      <customerID>abc</customerID> 
      <externalID>2</externalID> 
      <person> 
       <gender>M</gender> 
       <firstName>John</firstName> 
       <!-- here should be a middle name --> 
       <lastName>Doe</lastName> 
       <birthdate>2011-05-05</birthdate> 
      </person> 
      <!-- more elements... --> 
     </customer> 
     <!-- more elements... --> 
    </information > 
</document> 

和希望,正確的結果產生

<document> 
    <information type="person"> 
     <id>string</id> 
     <customer> 
     <customerID>abc</customerID> 
     <externalID>2</externalID> 
     <person> 
      <gender>M</gender> 
      <firstName>John</firstName> 
      <middleName>Fitzgerald</middleName><!-- here should be a middle name --> 
      <lastName>Doe</lastName> 
      <birthdate>2011-05-05</birthdate> 
     </person><!-- more elements... --> 
     </customer><!-- more elements... --> 
    </information> 
</document> 

討論

  1. 該解決方案是不是驚喜地試圖實現任何一種動態的評價簡單。

  2. 指定所需更改的XML文檔很緊湊。

  3. 邏輯很簡單,不像任何部分動態評估實現那樣複雜。

  4. 不需要額外的XSLT文檔。

  5. 這是一個簡單易用的實施,理解和維護解決方案。

+0

嗨和感謝您的想法,這裏的問題是,我需要以某種方式能夠處理更多的參數和更多的路徑......但也許增加第一步和修改路徑/值定義將允許獲得最好的兩個世界 – florent 2011-05-07 16:00:19

+0

@florent:這個想法是,編寫一個小而簡單的轉換,使得修改變得更容易和直接,而不是花大力氣去實現一個不完整和容易出錯的部分XPath表達式動態評估。時間「,每」下一次「需要額外的變化,並逐漸變成不可維護的怪物。比較這個怪物和小樣式表(也是一個XML文檔本身),並決定哪種方法更好:) – 2011-05-07 16:09:22

+0

我明白了,我正在尋找一個簡單而乾淨的解決方案(我知道怪物的風險)但我也有這個特定的約束。我也想確切地說,這不是一次性的轉變,而是一次重複的轉變。值來自用戶輸入,所以我們需要最少的「動態」評估。我也試圖找到應該動態的東西和應該修正的東西之間的正確界限(YAGNI和全部):) – florent 2011-05-08 11:10:43