2013-06-05 35 views
1

我們有一個程序使用xml來保存我們程序的配置。有人決定在我們的數據庫中重新命名一些值,這些重命名現在也應該在我們客戶的配置中向後兼容。用xslt重命名一批值

配置

<configuration> 
    <fruitToEat>yellow_curved_thing</fruitToEat> <!-- should now become banana --> 
</configuration> 

一個簡單的匹配將被(未測試,只是一個例子)的一個例子:

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

    <xsl:template match"/configuration/fruitToEat/text()"> 
    <xsl:text>banana</xsl:text> 
    </xsl:template> 
</xsl:template> 

但是,這只是一個示例,並且我想這樣做150倍。

是否有可能使xsl讀取一個簡單的文本文件或ini文件,告訴我150個匹配應該看起來相似?

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

    <!-- recreate this template 150 times from an ini file or something --> 
    <xsl:template match"/configuration/fruitToEat/text()[.='yellow_curved_thing']"> 
    <xsl:text>banana</xsl:text> 
    </xsl:template> 
</xsl:template> 

我的映射文件的一個例子可能是簡單的:

yellow_curved_thing = banana 
round_thing = tomato 
round_dotted = strawberry 

而且我只是想一個小XSLT,告訴我:

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

    <!-- recreate this template 150 times from an ini file or something --> 
    <xsl:template match"/configuration/fruitToEat/text()[.=$fileRow0]"> 
    <xsl:text>$fileRow1</xsl:text> 
    </xsl:template> 
</xsl:template> 
+0

如果將「ini文件」視爲xml文件,這應該不是什麼大問題。使用'select =「document('ini_file.xml')..」'來訪問這個過濾器。但是你的請求很難模糊地知道這是否合理,或者如果在xlst中明確實現這個規則會更好。 –

+0

所以我將不得不做一個新的XML,可以簡單地使所有規則的xslt顯式? – Marnix

回答

0

所以,即使我覺得幕後有更多的複雜性,可能會有所幫助。 有一些可能性用xlst來實現。從長遠來看哪個最好,取決於現實生活中的複雜程度,以及您需要多久才能用不同的「映射」信息來做到這一點。

爲了您的簡單示例,您可以將「映射」信息放入一個xml文件中。這可以通過一些腳本形式的ini文件來完成。

<mappings> 
    <mapping name="fruitToEat" > 
     <map from="yellow_curved_thing" to="banana" /> 
     <map from="round_thing" to="tomato" /> 
     <map from="round_dotted" to="strawberry" /> 
    </mapping> 
</mappings> 

比你能有一個模板,利用該映射信息:

<xsl:variable name="fruitMapping" 
      select="document('fruitmapping.xml')//mapping[@name='fruitToEat']" /> 

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

    <xsl:template match="/configuration/fruitToEat/text()" > 
     <!-- find the entry in "ini file" --> 
     <xsl:variable name ="map" select="$fruitMapping/map[@from = current()]" /> 
     <xsl:choose> 
      <xsl:when test="$map" > 
       <xsl:value-of select="$map/@to"/> 
      </xsl:when> 
      <xsl:otherwise> 
       <xsl:copy /> 
      </xsl:otherwise> 
     </xsl:choose> 
    </xsl:template> 

但如果這是我會實現這個「映射」一次性工作指引模板。像這樣:

<xsl:template match="/configuration/fruitToEat/text()" > 
    <xsl:choose> 
     <xsl:when test=".='yellow_curved_thing'" >banana</xsl:when> 
     <xsl:when test=".='round_thing'" >tomato</xsl:when> 
     <xsl:when test=".='round_dotted'" >strawberry</xsl:when> 
     <xsl:otherwise> 
      <xsl:copy /> 
     </xsl:otherwise> 
    </xsl:choose> 
</xsl:template> 
0

看來你想要的根據您的配置文件(也是XML文檔)創建您的XSLT動態XSLT。看看這個exmple考慮這個:

configuration.xml中

<p> 
    <configuration> 
    <fruitToEat>yellow_curved_thing</fruitToEat> 
    <mapped>banana</mapped> 
    </configuration> 
    <configuration> 
    <fruitToEat>round_thing</fruitToEat> 
    <mapped>tomato</mapped> 
    </configuration> 
</p> 

XSLT:

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

    <xsl:output method="xml" encoding="UTF-8" indent="yes" omit-xml-declaration="yes"/> 

    <xsl:template match="/"> 
    <xsl:element name="xsl:stylesheet"> 
     <xsl:attribute name="version"> 
     <xsl:text>1.0</xsl:text> 
     </xsl:attribute> 
     <xsl:element name="xsl:template"> 
     <xsl:attribute name="match"> 
      <xsl:text>node()|@*</xsl:text> 
     </xsl:attribute> 
     <xsl:element name="xsl:copy"> 
      <xsl:element name="xsl:apply-templates"> 
      <xsl:attribute name="select"> 
       <xsl:text>node()|@*</xsl:text> 
      </xsl:attribute> 
      </xsl:element> 
     </xsl:element> 
     </xsl:element> 
     <xsl:for-each select="//configuration"> 
     <xsl:element name="xsl:template"> 
      <xsl:attribute name="match"> 
      <xsl:text>configuration/fruitToEat/text()[.=</xsl:text> 
      <xsl:text>'</xsl:text> 
      <xsl:value-of select="fruitToEat"/> 
      <xsl:text>']</xsl:text> 
      </xsl:attribute> 
      <xsl:element name="xsl:text"> 
       <xsl:value-of select="mapped"/> 
      </xsl:element> 
     </xsl:element> 
     </xsl:for-each> 
    </xsl:element> 
    </xsl:template> 
</xsl:stylesheet> 

輸出:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> 
    <xsl:template match="node()|@*"> 
     <xsl:copy> 
     <xsl:apply-templates select="node()|@*"/> 
     </xsl:copy> 
    </xsl:template> 
    <xsl:template match="configuration/fruitToEat/text()[.='yellow_curved_thing']"> 
     <xsl:text>banana</xsl:text> 
    </xsl:template> 
    <xsl:template match="configuration/fruitToEat/text()[.='round_thing']"> 
     <xsl:text>tomato</xsl:text> 
    </xsl:template> 
</xsl:stylesheet> 
+0

您是否正在考慮將xsl應用於配置以獲取新的xsl?那不是我想要的。在輸出中,我缺少從「yellow_curved」,「round_red」和「round_dotted」映射的「香蕉」,「番茄」,「草莓」。 – Marnix

+0

從哪裏你想選擇這個信息'香蕉','番茄'等。這些信息也在配置文件?您可以增強我的共享XML文件以保留這些信息,以便您可以輕鬆操縱它。 –

+0

是的我想要一個ini文件或其中包含一個名稱映射到另一個名稱的東西。我認爲這會很容易讀取文件並生成xslt,但似乎很難構建,而不是通過C#或其他東西來生成。 – Marnix