2011-05-05 42 views
1

我extrating一些數據移出此XML文件的一個問題:在XSLT中創建動態變量名稱,或者如何解決這個問題?

<?xml version="1.0" encoding="UTF-8"?> 
<ph:Graphs xmlns:ph="http://www.merge.something.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<ph:Graph name="mass_spring_mo"> 
    <ph:Element id="0" type="Fixed"> 
     <ph:Port id="1" type="port"> 
      <ph:Attribute> 
       <ph:AttributeField name="type" value="string"/> 
       <ph:AttributeField name="name" value="type"/> 
       <ph:AttributeField name="value" value="flange"/> 
      </ph:Attribute> 
     </ph:Port> 
    </ph:Element> 
    <ph:Element id="2" type="Spring"> 
     <ph:Attribute> 
      <ph:AttributeField name="type" value="int"/> 
      <ph:AttributeField name="name" value="s_rel0"/> 
      <ph:AttributeField name="value" value="5"/> 
     </ph:Attribute> 
     <ph:Port id="3" type="port"> 
      <ph:Attribute> 
       <ph:AttributeField name="type" value="string"/> 
       <ph:AttributeField name="name" value="type"/> 
       <ph:AttributeField name="value" value="flange_a"/> 
      </ph:Attribute> 
     </ph:Port> 
    </ph:Element> 
    <ph:Edge id="17" sourceid="1" targetid="3"/> 
</ph:Graph> 
</ph:Graphs> 

所以我創造了這個XSLT文件:

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ph="http://www.merge.something.com"> 

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

    <xsl:template match="/"> 
      <xsl:apply-templates select="ph:Graphs/ph:Graph"/> 
    </xsl:template> 

    <xsl:template match="ph:Graph"> 
     <xsl:text>model </xsl:text> 
     <xsl:value-of select="@name"/> 
     <xsl:text> 
     </xsl:text> 
      <xsl:apply-templates select="ph:Element"/> 
     <xsl:text> 
     </xsl:text> 
     <xsl:text>equation</xsl:text> 
     <xsl:text> 
     </xsl:text> 
      <xsl:apply-templates select="ph:Edge"/> 
     <xsl:text>end </xsl:text> 
     <xsl:value-of select="@name"/> 
     <xsl:text>;</xsl:text> 
    </xsl:template> 

    <xsl:template match="ph:Element"> 
     <xsl:variable name="type" select="@type"/> 
     <xsl:variable name="id" select="@id"/> 

     <xsl:text>Components.</xsl:text> 
     <xsl:value-of select="@type"/> 
     <xsl:text > </xsl:text> 
     <xsl:value-of select="@type"/><xsl:value-of select="@id"/> 
      <xsl:apply-templates select="ph:Port/ph:Attribute"/> 
    </xsl:template> 

    <xsl:template match="ph:Port/ph:Attribute"> 
     <xsl:if test="ph:AttributeField/@value=type"> 
      <xsl:apply-templates select="ph:AttributeField"/> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="ph:AttributeField"> 
    </xsl:template> 

    <xsl:template match="ph:Edge"> 
     <xsl:text>connect(</xsl:text> 
     <xsl:text >);</xsl:text> 
     <xsl:text> 
     </xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 

輸出應該看起來像:

model mass_spring_mo 
Components.Fixed fixed1; 
Components.Spring spring1(s_rel0 = 10); 
equation 
connect(fixed1.flange,spring1.flange_a); 
end mass_spring_mo; 

我的問題是獲取應該連接的元素的名稱和類型。我試圖用id = 1等動態名稱來生成變量,但它不起作用。 也許有一個更簡單的方法來引用元素的屬性!?

如果有人能給我一個提示,我會非常感激。

謝謝,再見 米歇爾

+0

你還沒有解釋任何東西。 「應該連接的元素」是什麼意思?這個XML文檔的語義是什麼?一點也不清楚。在目前的形式下,這不是一個明確定義的問題。請編輯/改進。 – 2011-05-05 15:26:15

回答

2

這裏是一個模板。 你可以看到我用了一種不同的方法來處理線條結尾。 也可以通過在ph:Edge模板中定義SourceElement和TargetElement變量來完成回顧。我只需選擇具有與ph:Edge的sourceid屬性相匹配的相應ph:Port子元素的ph:Element元素。一旦你可以識別這些,引用它們的屬性就足夠簡單了。

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ph="http://www.merge.something.com"> 

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

    <xsl:template match="/"> 
      <xsl:apply-templates select="ph:Graphs/ph:Graph"/> 
    </xsl:template> 

    <xsl:template match="ph:Graph"> 
     <xsl:text>model </xsl:text><xsl:value-of select="@name"/><xsl:text>&#10;</xsl:text> 
     <xsl:apply-templates select="ph:Element"/> 
     <xsl:text>equation&#10;</xsl:text> 
     <xsl:apply-templates select="ph:Edge"/> 
     <xsl:text>end </xsl:text><xsl:value-of select="@name"/><xsl:text>;</xsl:text> 
    </xsl:template> 

    <xsl:template match="ph:Element"> 
     <xsl:text> Components.</xsl:text><xsl:value-of select="@type"/><xsl:text > </xsl:text> 
     <xsl:value-of select="translate(@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')"/><xsl:value-of select="@id"/> 
     <xsl:apply-templates select="ph:Attribute"/> 
     <xsl:text>;&#10;</xsl:text> 
    </xsl:template> 

    <xsl:template match="ph:Element/ph:Attribute"> 
     <xsl:choose> 
      <xsl:when test="ph:AttributeField[@name = 'type' and @value='int']"> 
       <xsl:text>(</xsl:text><xsl:value-of select="ph:AttributeField[@name = 'name']/@value"/><xsl:text> = </xsl:text><xsl:value-of select="ph:AttributeField[@name = 'value']/@value" /><xsl:text>)</xsl:text> 
      </xsl:when> 
      <xsl:when test="ph:AttributeField[@name = 'type' and @value='string']"> 
       <xsl:text>(</xsl:text><xsl:value-of select="ph:AttributeField[@name = 'name']/@value"/><xsl:text> = '</xsl:text><xsl:value-of select="ph:AttributeField[@name = 'value']/@value" /><xsl:text>')</xsl:text> 
      </xsl:when> 
     </xsl:choose> 
    </xsl:template> 

    <xsl:template match="ph:Port/ph:Attribute"> 
     <xsl:if test="ph:AttributeField/@value=type"> 
      <xsl:apply-templates select="ph:AttributeField"/> 
     </xsl:if> 
    </xsl:template> 

    <xsl:template match="ph:AttributeField"> 
    </xsl:template> 

    <xsl:template match="ph:Edge"> 
     <xsl:variable name="sourceid" select="@sourceid"/> 
     <xsl:variable name="targetid" select="@targetid"/> 
     <xsl:variable name="SourceElement" select="//ph:Element[ph:Port[@id = $sourceid]]"/> 
     <xsl:variable name="TargetElement" select="//ph:Element[ph:Port[@id = $targetid]]"/> 
     <xsl:text> connect(</xsl:text> 
     <xsl:value-of select="translate($SourceElement/@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" /> 
     <xsl:value-of select="$SourceElement/@id" /> 
     <xsl:text>.</xsl:text> 
     <xsl:value-of select="$SourceElement/ph:Port/ph:Attribute/ph:AttributeField[@name = 'value']/@value" /> 
     <xsl:text>,</xsl:text> 
     <xsl:value-of select="translate($TargetElement/@type, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz')" /> 
     <xsl:value-of select="$TargetElement/@id" /> 
     <xsl:text>.</xsl:text> 
     <xsl:value-of select="$TargetElement/ph:Port/ph:Attribute/ph:AttributeField[@name = 'value']/@value" /> 
     <xsl:text >);&#10;</xsl:text> 
    </xsl:template> 

</xsl:stylesheet> 
+0

好的!我認爲將標識符構造(使用'translate(...)')提取到一個單獨的模板中(傳遞適當的'ph:Element'節點作爲參數)甚至可以使用變量'$ uppercase'和' $小寫'爲可讀性... – mousio 2011-05-05 18:54:56

+0

非常感謝你會爲你的答案,它的作品找到。我還有一個問題:如果有多於一個,但輸出應該看起來像'(s_rel0 = 10,var2 = 12)',我該如何處理'ph:Element'的''。如果還有更多'ph:Port'屬性!? – Michele 2011-05-06 18:17:41

+0

更多ph:端口應該已被處理,因爲它在端口的id屬性上匹配。至於多元ph:Element/ph:Attribute,你必須將一些東西移動到ph:Element模板,就像(和)一樣。我也可能會做一個foreach ph:Attribute,以便插入逗號。 – 2011-05-09 14:07:11

相關問題