2016-11-04 210 views
0

我試圖在xml中使用xslt 1.0(使用visual studio 2015)轉換。XSLT 1.0轉換覆蓋或添加子節點

我給了房子的名稱和應該在房子內的傢俱的名稱和新值。

如果具有給定名稱的傢俱已經存在,請覆蓋其值。
如果沒有,請創建一個新的。
如果傢俱在家中但不應被覆蓋,只需複製它。
已經在家裏的傢俱的訂單不應該改變。

我對C++,C#,JAVA等語言並不陌生,但xslt是......不同的。 雖然在上述語言中這是一個簡單的任務,但我真的在這裏掙扎。

請幫忙。

XML代碼

<Street> 
    <House Name="house1"> 
    <Window>niceView</Window> 
    <Furniture Name="name1">value1</Furniture> 
    <Furniture Name="name2">value2</Furniture> 
    <Furniture Name="name3">value3</Furniture> 
    <Furniture Name="name4">value4</Furniture>  
    </House> 
    <House> 
    <Brick Name="cubrick"></Brick> 
    <Furniture name="name1>value</Furniture> 
    </House> 
</Street> 

XSLT beggining

<?xml version="1.0" encoding="utf-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" indent="yes"/> 

<xsl:param name="house1" select='house1'/> 
<xsl:param name="name2" select='newValue1'/> 
<xsl:param name="name4" select='newValue2'/> 
<xsl:param name="name10" select='newValue5'/> 
... 

所需的輸出是:

<Street> 
    <House Name="house1"> 
    <Window>niceView</Window> 
    <Furniture Name="name1">value1</Furniture> 
    <Furniture Name="name2">newValue1</Furniture> 
    <Furniture Name="name3">value3</Furniture> 
    <Furniture Name="name4">newValue2</Furniture> 
    <Furniture Name="name10">newValue5</Furniture> 
    </House> 
    <House> 
    <Brick Name="cubrick"></Brick> 
    <Furniture name="name1>value</Furniture> 
    </House> 
</Street> 
+0

我不明白你的輸出爲第二'' House'。 –

+0

Sry,那是一個錯字。那第二間房子根本不變。它可能會或可能沒有屬性名稱。它可能有任何東西。我只對屬性Name = $ house1的House感興趣。 –

+0

您確定需要參數化所顯示的值嗎?這非常尷尬,因爲您無法通過名稱輕鬆選擇參數。 –

回答

0

根據您的意見,我會建議你考慮以下方法:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:exsl="http://exslt.org/common" 
extension-element-prefixes="exsl"> 
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<!-- MODIFY THESE AS NECESSARY --> 
<xsl:param name="my-house">house1</xsl:param> 

<xsl:variable name="my-values"> 
    <Furniture Name="name2">newValue2</Furniture> 
    <Furniture Name="name4">newValue4</Furniture> 
    <Furniture Name="name10">newValue10</Furniture> 
</xsl:variable> 

<!-- DO NOT MODIFY FROM THIS POINT ON --> 
<xsl:variable name="user-values" select="exsl:node-set($my-values)/Furniture" /> 

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

<xsl:template match="House"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()"/> 
     <xsl:if test="@Name=$my-house"> 
      <!-- add missing nodes --> 
      <xsl:copy-of select="$user-values[not(@Name=current()/Furniture/@Name)]"/> 
     </xsl:if> 
    </xsl:copy> 
</xsl:template> 

<xsl:template match="Furniture"> 
    <xsl:variable name="override" select="$user-values[@Name=current()/@Name]"/> 
    <Furniture Name="{@Name}"> 
     <xsl:choose> 
      <xsl:when test="../@Name=$my-house and $override"> 
       <xsl:value-of select="$override" /> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:value-of select="." /> 
      </xsl:otherwise> 
     </xsl:choose> 
    </Furniture> 
</xsl:template> 

</xsl:stylesheet> 

當施加到下面的合式例如輸入(!):

XML

<Street> 
    <House Name="house1"> 
    <Window>niceView</Window> 
    <Furniture Name="name1">value1</Furniture> 
    <Furniture Name="name2">value2</Furniture> 
    <Furniture Name="name3">value3</Furniture> 
    <Furniture Name="name4">value4</Furniture>  
    </House> 
    <House> 
    <Brick Name="cubrick"></Brick> 
    <Furniture Name="name1">value</Furniture> 
    </House> 
</Street> 

結果將是:

<?xml version="1.0" encoding="UTF-8"?> 
<Street> 
    <House Name="house1"> 
     <Window>niceView</Window> 
     <Furniture Name="name1">value1</Furniture> 
     <Furniture Name="name2">newValue2</Furniture> 
     <Furniture Name="name3">value3</Furniture> 
     <Furniture Name="name4">newValue4</Furniture> 
     <Furniture Name="name10">newValue10</Furniture> 
    </House> 
    <House> 
     <Brick Name="cubrick"/> 
     <Furniture Name="name1">value</Furniture> 
    </House> 
</Street> 
+0

非常感謝!你幫助我理解了我甚至不知道的一些概念。還有一個問題:爲什麼你在這個腳本中使用是強制性還是隻是好的做法的一部分? –

+0

** 1。**這是一個很好的做法。當使用身份轉換模板時(它減少了處理器需要處理的節點數量); ** 2。**一些處理器(特別是Saxon 6.5)如果不包含它將輸出空行 - 請參閱:http://xsltransform.net/94AbWB7 –

+0

再次感謝!我一定會牢記這一點。 –