2011-06-08 142 views
2

在XML嵌套的元素我有一個平坦的XML看起來像這樣:無法創建使用XLST

<objectDataList> 
<objectData> 
    <equipment> 
     <name>Chassis-One</name> 
     <type>Chassis</type> 
    </equipment> 
</objectData> 
<objectData> 
    <equipment> 
     <name>Shelf-One</name> 
     <type>Shelf</type> 
    </equipment> 
</objectData> 
<objectData> 
    <equipment> 
     <name>Shelf-Two</name> 
     <type>Shelf</type> 
    </equipment> 
</objectData> 
<objectData> 
    <equipment> 
     <name>Slot-One</name> 
     <type>Slot</type> 
    </equipment> 
</objectData> 

如何創建一個XSL,將改變我的XML到另一個XML,看起來像這樣的:

<equipments> 
<object> 
    <name>Chassis-One</name> 
     <object> 
      <name>Shelf-One</name> 
      <object> 
       <name>Slot-One</name> 
      </object> 
     </object> 

</object> 

這就像在一個機箱中,有2架,並在貨架一個,有槽-One ..

我中途試過,但我想不出如何使嵌套的元素:

<xsl:template match="/response"> 
    <equipments>    
      <object> 
       <xsl:apply-templates select="objectData"/> 
      </object> 
    </equipments> 

<xsl:template match="objectData/equipment[type='Chassis']"> 
    <name><xsl:value-of select="equipment/name"/></name> 
     <!-- Now I want to find the shelf according to the chassis name --> 
     <xsl:call-template name="find-shelf-according-to-chasis-name"> 
      <xsl:with-param name="chassisName" select="equipment/name"/> 
     </xsl:call-template> 
</xsl:template> 

我希望有人能擺脫一些光

謝謝你提前

+0

除了姓名約定,應該如何腳本上的節點之間的父子關係決定? – rsp 2011-06-08 08:15:28

+0

基於 =「%-One」..基本上如果貨架名稱是Shelf-One,那麼它將屬於Chassis-One ..並且如果插槽名稱是SLot-One,那麼它將屬於貨架-One .. – rainingDay 2011-06-08 08:22:41

+0

在您的示例中,您將貨架二放置在機箱一之下。如果輸入中缺少Chassic-Two,它是否應該在輸出中? – rsp 2011-06-08 08:43:23

回答

0

有一個相當簡單(雖然有點冗長)解決方案:

<xsl:template match="objectDataList"> 
    <equipments> 
    <xsl:apply-templates select="objectData[equipment/type='Chassis']"/> 
    </equipments> 
</xsl:template> 

<xsl:template match="objectData[equipment/type='Chassis']"> 
    <xsl:variable name="index" select="substring-after(equipment/name,'-')" /> 
    <object> 
    <xsl:copy-of select="equipment/name" /> 
    <xsl:apply-templates select="following-sibling::objectData[equipment/type='Shelf' and substring-after(equipment/name,'-') = $index]" /> 
    </object> 
</xsl:template> 

<xsl:template match="objectData[equipment/type='Shelf']"> 
    <xsl:variable name="index" select="substring-after(equipment/name,'-')" /> 
    <object> 
    <xsl:copy-of select="equipment/name" /> 
    <xsl:apply-templates select="following-sibling::objectData[equipment/type='Slot' and substring-after(equipment/name,'-') = $index]" /> 
    </object> 
</xsl:template> 

<xsl:template match="objectData[equipment/type='Slot']"> 
    <xsl:variable name="index" select="substring-after(equipment/name,'-')" /> 
    <object> 
    <xsl:copy-of select="equipment/name" /> 
    </object> 
</xsl:template> 

這是一個有點重複,雖然,最後的三個模板幾乎是相同的。但是,根據您的具體要求,可能有助於他們處理不同的模板。

如果你能保證貨架將始終遵循相關的底盤等,那麼您可以在第二個模板改變<xsl:apply-templates到:

<xsl:apply-templates select="following-sibling::*[1]">

如果有可能不是一個,那麼你就可以更多信息:

<xsl:apply-templates select="following-sibling::*[1][equipment/type='Shelf']">

+0

謝謝Flynn1179,它工作的很好。是的,機箱的插槽層次結構是固定的,因此我按照您的建議更改了第二個模板!再次感謝:) – rainingDay 2011-06-08 09:35:57

+0

酷..如果你曾經在架子上得到一個底盤,但你知道它不像你想象的那樣固定:) – Flynn1179 2011-06-08 09:39:06

0

下面的腳本會做你想做的,它由於Chassis-Shelf-Slot結構必須在腳本中表示,因此有點冗長。如果你的xml包含id和parent-id屬性,腳本可能會變小,命名規則可能會被刪除或放寬。

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 

    <xsl:output method="xml"/> 

    <xsl:template match="/"> 
    <equipments> 
    <xsl:apply-templates select="//equipment[type='Chassis']" /> 
    </equipments> 
    </xsl:template> 

    <xsl:template match="equipment[type='Chassis']"> 
    <xsl:variable name="suffix" select="substring-after(name, '-')" /> 
    <object> 
     <xsl:copy-of select="name" /> 
     <xsl:apply-templates select="//equipment[type='Shelf'][substring-after(name, '-')=$suffix]" /> 
    </object> 
    </xsl:template> 


    <xsl:template match="equipment[type='Shelf']"> 
    <xsl:variable name="suffix" select="substring-after(name, '-')" /> 
    <object> 
     <xsl:copy-of select="name"/> 
     <xsl:apply-templates select="//equipment[type='Slot'][substring-after(name, '-')=$suffix]" /> 
    </object> 
    </xsl:template> 

    <xsl:template match="equipment[type='Slot']"> 
    <object> 
     <xsl:copy-of select="name"/> 
    </object> 
    </xsl:template> 

</xsl:stylesheet> 

你問的部分採用substring-after函數來確定後綴名,並使用在隨後的選擇。

+0

已經修復。感謝rsp,你的工作也很好。是的,太糟糕了,我原來的xml沒有id/parent-id屬性,它只基於名字.. – rainingDay 2011-06-08 09:39:08