我正在處理一個需要複製和更新以傳遞進行進一步處理的xml。我遇到的問題是我沒有想出一個有效的方法來做到這一點。實質上,我想有條件地更新一些數據,然後複製所有未更新的節點。爲什麼這是具有挑戰性的,是由於要複製的節點的數量和名稱的數量和方差。我也不想複製沒有文本值的節點。下面是一個例子:使用XSLT有選擇地複製和更新xml節點
INPUT XML
<root>
<PersonProfile xmlns:'namespace'>
<ID>0001</ID>
<Name>
<FirstName>Jonathan</FirstName>
<PreferredName>John</PreferredName>
<MiddleName>A</MiddleName>
<LastName>Doe</LastName>
</Name>
<Country>US</Country>
<Biirthdate>01-01-1980</Birthdate>
<BirthPlace>
<City>Townsville</City>
<State>OR</State>
<Country>US</Country>
</Birthplace>
<Gender>Male</Gender>
<HomeState>OR</HomeState>
...
<nodeN>text</nodeN>
</PersonProfile>
</root>
的「PersonProfile」節點僅僅是「根」元素內的幾個節點集,每個都有自己的數據的子集的一個。比如郵寄地址,緊急聯繫信息等等。我試圖做的是更新節點,如果變量有一個新的值,那麼複製所有未更新的節點。
這裏是我當前的XSLT
<xsl:stylesheet version="2.0" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<xsl:variable name='updateData' select='document("report")'/>
<!-- Identity Transform -->
<xsl:template match='@* | node()'>
<xsl:if test'. != ""'>
<xsl:copy>
<xsl:apply-templates select='@* | node()'/>
</xsl:copy>
</xsl:if>
</xsl:template>
<!-- Template to update Person Profile -->
<xsl:template match='PersonProfile'>
<xsl:copy>
<xsl:apply-templates select='*'/>
<xsl:element name='Name'>
<xsl:if test='exists($updateData/Preferred)'>
<xsl:element name='FirstName'>
<xsl:value-of select='$reportData/FirstName'/>
</xsl:element>
</xsl:if>
<xsl:if test='exists($updateData/Preferred)'>
<xsl:element name='PreferredName'>
<xsl:value-of select='$updateData/Preferred'/>
</xsl:element>
</xsl:if>
<xsl:if test='exists($updateData/Middle)'>
<xsl:element name='MiddleName'>
<xsl:value-of select='$updateData/Middle'/>
</xsl:element>
</xsl:if>
<xsl:if test='exists($updateData/LastName)'>
<xsl:element name='LastName'>
<xsl:value-of select='$updateData/wd:LastName'/>
</xsl:element>
</xsl:if>
</xsl:element>
<xsl:if test='exists($updateData/Country)'>
<xsl:element name='Country'>
<xsl:value-of select='$updateData/Country'/>
</xsl:element>
</xsl:if>
....
<!-- follows same structure until end of template -->
</xsl:copy>
</xsl:template>
<!-- More Templates to Update other Node sets -->
</xsl:stylesheet>
發生了什麼事,現在,是它的複製所有的節點,然後添加更新的值。使用撒克遜PE 9.3.0.5,我會得到類似這樣的輸出:
樣本輸出
<root>
<PersonProfile xmlns:'namespace'>
<ID>0001</ID>
<Name>
<FirstName>Jonathan</FirstName>
<PreferredName>John</PreferredName>
<MiddleName>A</MiddleName>
<LastName>Doe</LastName>
</Name>
<Country>US</Country>
<Biirthdate>01-01-1980</Birthdate>
<BirthPlace>
<City>Townsville</City>
<State>OR</State>
<Country>US</Country>
</Birthplace>
<Gender>Male</Gender>
<HomeState>OR</HomeState>
...
<nodeN>text</nodeN>
<PreferredName>Jonathan</PreferredName>
<HomeState>WA</HomeState>
</PersonProfile>
</root>
我意識到這種情況正在發生,因爲我在PersonProfile應用模板到所有節點並且我可以指定排除哪些節點,但是我覺得這是一個非常糟糕的解決方案,因爲節點的體積可能超過30個或更多,並且需要每個節點的書面值。我相信XML比明確列出每個節點更優雅。我想有一個出這樣的:
所需的輸出
<root>
<PersonProfile xmlns:'namespace'>
<ID>0001</ID>
<Name>
<FirstName>Jonathan</FirstName>
<PreferredName>Jonathan</PreferredName>
<MiddleName>A</MiddleName>
<LastName>Doe</LastName>
</Name>
<Country>US</Country>
<Biirthdate>01-01-1980</Birthdate>
<BirthPlace>
<City>Townsville</City>
<State>OR</State>
<Country>US</Country>
</Birthplace>
<Gender>Male</Gender>
<HomeState>WA</HomeState>
...
<nodeN>text</nodeN>
</PersonProfile>
</root>
如果有人可以幫助我建立一個模板結構,將在XML結構的工作,我將不勝感激。它需要是「可重用的」,因爲有類似的節點結構,比如我需要應用它的Person Profile,但節點名稱和元素數量不同,等等。
- Ĵ
所以我找到了一個潛在的解決方案,基本上我爲每個xpath創建了一個模板,可以更新然後應用它們 - 哪個工作得很好。我只有1個問題 - 當路徑不存在時如何使用模板!可以說這個人缺少主頁狀態 - 我無法匹配做,所以我怎麼能告訴模板來建立新的節點? 謝謝! – 2013-02-26 03:10:04