2016-02-06 41 views
0

我想學習xslt作爲一種興趣,而我感興趣的用例之一就是將某些組件的定義擴展到其完整形式。一個例子應該澄清我的意思。例如如果我的輸入XML的樣子:使用xslt擴展compact xml表示形式到更詳細的表示形式

<universe> 
    <galaxies> 
     <galaxy name="milky way"> 
      <system name="solar system"/> 
     </galaxy> 
     <galaxy name="lactose free"> 
      <system name="windmill system"/> 
     </galaxy> 
     <galaxy name="parallelish solar system"> 
      <system name="the earth system"/> 
     </galaxy> 
    </galaxies> 
    <systems> 
     <system name="solar system"> 
      <planet name="pluto"/> 
      <system name="the earth system"/> 
      <planet name="mercury"/> 
     </system> 
     <system name="windmill system"> 
      <planet name="windy"/> 
     </system> 
     <system name="the earth system"> 
      <planet name="earth"/> 
      <satellite name="moon"/> 
     </system> 
    </systems> 
</universe> 

我的XML輸出會在星系的定義擴大遞歸這些系統定義(例如,在太陽系中地球系統)和定義出現的每一個地方(如地球系統發生在兩個不同的系統中)。該系統部分將被刪除:

<universe> 
    <galaxies> 
     <galaxy name="milky way"> 
      <system name="solar system"> 
       <planet name="pluto"/> 
       <system name="the earth system"> 
        <planet name="earth"/> 
        <satellite name="moon"/> 
       </system> 
       <planet name="mercury"/> 
      </system> 
     </galaxy> 
     <galaxy name="lactose free"> 
      <system name="windmill system"> 
       <planet name="windy"/> 
      </system> 
     </galaxy> 
     <galaxy name="parallelish solar system"> 
      <system name="the earth system"> 
       <planet name="earth"/> 
       <satellite name="moon"/> 
      </system> 
     </galaxy> 
    </galaxies> 
</universe> 

我非常新XSLT和截至目前,我已經按照思想的線已經以某種方式定義這些組件塊變量和將它們插入(第二場)合格。但是,正如我搜索一下並閱讀了一些試圖找到示例的內容,我一直沒有取得成功。我想知道這是否可能(我期望如此),以及我需要使用什麼概念來實現這一點。示例代碼片段會非常有幫助。

謝謝!

回答

0

XSLT有一個非常有用的keys解決交叉引用的機制。爲了演示它如何工作的,我第一次修改您的XML例子,以避免循環引用:

XML

<universe> 
    <galaxies> 
     <galaxy name="milky way"> 
      <system-ref name="solar system"/> 
     </galaxy> 
     <galaxy name="lactose free"> 
      <system-ref name="windmill system"/> 
     </galaxy> 
     <galaxy name="parallelish solar system"> 
      <system-ref name="the earth system"/> 
     </galaxy> 
    </galaxies> 
    <systems> 
     <system name="solar system"> 
      <planet name="pluto"/> 
      <system-ref name="the earth system"/> 
      <planet name="mercury"/> 
     </system> 
     <system name="windmill system"> 
      <planet name="windy"/> 
     </system> 
     <system name="the earth system"> 
      <planet name="earth"/> 
      <satellite name="moon"/> 
     </system> 
    </systems> 
</universe> 

XSLT

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

<xsl:key name="system-by-name" match="system" use="@name" /> 

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

<xsl:template match="system-ref"> 
    <xsl:apply-templates select="key('system-by-name', @name)"/> 
</xsl:template> 

<xsl:template match="systems"/> 

</xsl:stylesheet> 

結果

<?xml version="1.0" encoding="UTF-8"?> 
<universe> 
    <galaxies> 
     <galaxy name="milky way"> 
     <system name="solar system"> 
      <planet name="pluto"/> 
      <system name="the earth system"> 
       <planet name="earth"/> 
       <satellite name="moon"/> 
      </system> 
      <planet name="mercury"/> 
     </system> 
     </galaxy> 
     <galaxy name="lactose free"> 
     <system name="windmill system"> 
      <planet name="windy"/> 
     </system> 
     </galaxy> 
     <galaxy name="parallelish solar system"> 
     <system name="the earth system"> 
      <planet name="earth"/> 
      <satellite name="moon"/> 
     </system> 
     </galaxy> 
    </galaxies> 
</universe> 
+0

謝謝你的幫助邁克爾!我現在開始閱讀鑰匙,謝謝你指出。 –

+0

我還發現,對於我的特殊情況,使用我發佈的原始xml隱式區分系統/系統(定義)與系統引用,以及下面更具體的模板匹配會更自然: 閱讀有關閱讀排除比賽也是如此(例如不(系統/系統))。 –