2013-02-25 49 views
0

我在輸入文件,變量和類型兩個標記:XSLT:從一個與另一個與變換/映射合併使用屬性的兩個標籤,標籤

<variable baseType="int" name="X"> 
</variable> 

<type baseType="structure" name="Y"> 
    <variableInstance name="X" /> 
</type> 

,我需要生成以下輸出文件:

<Item name="Y"> 
    <Field name="X" type="Long" /> 
</Item> 

所以這裏概念我的做法一直類型標籤轉換成項目踏歌,變量實例字段。這是工作的罰款:

<xsl:for-each select="type[@baseType='structure']"> 
    <Item> 
     <xsl:attribute name="name"><xsl:value-of select="@name" /></xsl:attribute> 
     <xsl:for-each select="variableInstance"> 
      <Field> 
       <xsl:attribute name="name"><xsl:value-of select="@name" /></xsl:attribute> 
       <xsl:attribute name="type">**THIS IS WHERE I'M STUCK**</xsl:attribute> 
      </Field> 
     </xsl:for-each> 
    </Item> 
</xsl:for-each> 

我卡上的問題是:

  1. 我不知道如何讓variableInstance /字段標籤匹配的名字變量標籤,所以我可以訪問baseType。
  2. 我要地圖「INT」,以「龍」一旦我能夠做到1

提前感謝!

回答

1

問題1.

對於你有,你可以使用一個關鍵的第一個問題:

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

這關鍵是要索引文檔中的所有變量元素,用他們的名字。所以,現在,我們可以通過下面的XPath表達式訪問任何這些元素:

key('variable-key', 'X') 

使用這種方法是有效的,當你有很多可變因素。

注意:如果每個變量都有自己的作用域(即局部變量在文檔的不同部分不可見),則此方法無效。在這種情況下,應該修改這種方法。

問題2.

對於映射屬性,你可以使用模板類似如下:

<xsl:template match="@baseType[. = 'int']"> 
     <xsl:attribute name="baseType"> 
      <xsl:value-of select="'Long'" /> 
     </xsl:attribute> 
    </xsl:template> 

這種轉變的含義是:每次我們爲int值BASETYPE屬性與時間,它必須被Long值所取代。

此轉換將適用於文檔中的每個@baseType屬性。


使用描述策略的解決方案可能是:

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

    <xsl:output method="xml" indent="yes" /> 

    <!-- Index all variable elements in the document by name --> 
    <xsl:key name="variable-key" 
      match="//variable" 
      use="@name" /> 

    <!-- Just for demo --> 
    <xsl:template match="text()" /> 

    <!-- Identity template: copy attributes by default --> 
    <xsl:template match="@*"> 
     <xsl:copy> 
      <xsl:value-of select="." /> 
     </xsl:copy> 
    </xsl:template> 

    <!-- Match the structure type --> 
    <xsl:template match="type[@baseType='structure']"> 
     <Item> 
      <xsl:apply-templates select="*|@*" /> 
     </Item> 
    </xsl:template> 

    <!-- Match the variable instance --> 
    <xsl:template match="variableInstance"> 
     <Field> 
      <!-- Use the key to find the variable with the current name --> 
      <xsl:apply-templates select="@*|key('variable-key', @name)/@baseType" /> 
     </Field> 
    </xsl:template> 

    <!-- Ignore attributes with baseType = 'structure' --> 
    <xsl:template match="@baseType[. = 'structure']" /> 

    <!-- Change all baseType attributes with long values to an attribute 
     with the same name but with an int value --> 
    <xsl:template match="@baseType[. = 'int']"> 
     <xsl:attribute name="baseType"> 
      <xsl:value-of select="'Long'" /> 
     </xsl:attribute> 
    </xsl:template> 

</xsl:stylesheet> 

這代碼將下面的XML文檔轉換:

<!-- The code element is present just for demo --> 
<code> 
    <variable baseType="int" name="X" /> 
    <type baseType="structure" name="Y"> 
     <variableInstance name="X" /> 
    </type> 
</code> 

<Item name="Y"> 
    <Field baseType="Long" name="X"/> 
</Item> 
+0

嘿帕布羅,那太好了。我對xsl:key標籤缺乏瞭解是什麼阻止了我。在我的代碼中快速入侵現在正在工作。非常感謝! – 2013-02-25 15:52:55

+0

乾杯,很高興我能幫上忙。 – 2013-02-25 15:56:23

+0

如果我的答案解決了您的問題,您是否介意將其標記爲已接受的答案?謝謝 – 2013-02-26 15:58:02

0

衝電氣我有一個解決方案t 1 xsltcake slicewith use of templates。對於第二點,我可能會使用與Pablo Pozo在他的回答中使用的模板類似的模板

相關問題