2013-07-09 158 views
0

我想寫一個XSLT樣式表,它通過一些映射規則映射元素名稱。爲了使樣式表自定義爲經驗不足的用戶我想這樣seperatly存儲地圖的樣式表中:XSLT映射元素名稱

<mr:mapping-rules> 
    <field src="field1" dest="field1337" /> 
    <field src="field2" dest="field2" /> 
    <field src="field3" dest="field3" /> 
</mr:mapping-rules> 

下面是一些例子輸入數據:

<Record> 
    <field1>123</field1> 
    <field2>asd</field2> 
    <field3>456</field3> 
</Record> 

預期的結果是:

<Record> 
    <field1337>123</field1337> 
    <field2>asd</field2> 
    <field3>456</field3> 
</Record> 

這將是很好,如果有人可以給我一個提示如何模板必須看起來像。

+0

首先,我會建議不要列出哪些領域不應該改變。然後我想知道映射是否需要包含像父代或祖先路徑一樣的上下文。然後我會建議通過編寫一個帶有映射文件的樣式表來解決問題,並生成一個新的樣式表,以實現給定映射文件的特定映射。 –

回答

1

這是一個建議,根據我所做的評論。我寫一個樣式表採取的映射文件的形式

<mr:mapping-rules xmlns:mr="http://example.com/mr"> 
    <context pattern="Record"> 
    <field src="field1" dest="field1337" /> 
    </context> 
</mr:mapping-rules> 

在形式

<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="Record/field1"> 
     <xsl:element name="field1337"> 
     <xsl:apply-templates select="@* | node()"/> 
     </xsl:element> 
    </xsl:template> 

</xsl:stylesheet> 

創建上述樣式表作爲它的輸出是

<xsl:stylesheet 
    version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:mr="http://example.com/mr" 
    xmlns:oxsl="http://example.com/xsl" 
    exclude-result-prefixes="oxsl mr"> 

<xsl:namespace-alias stylesheet-prefix="oxsl" result-prefix="xsl"/> 

<xsl:output indent="yes"/> 

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

<xsl:template match="mr:mapping-rules/context/field"> 
    <oxsl:template match="{../@pattern}/{@src}"> 
    <oxsl:element name="{@dest}"> 
     <oxsl:apply-templates select="@* | node()"/> 
    </oxsl:element> 
    </oxsl:template> 
</xsl:template> 

</xsl:stylesheet> 

的樣式表來生成一個樣式表然後,您可以在輸入上運行生成的樣式表,如

<Root> 
    <Record-List> 
    <Record> 
     <field1>foo</field1> 
     <field2>bar</field2> 
     <field3>baz</field3> 
    </Record> 
    </Record-List> 
</Root> 

並輸出

<Root> 
    <Record-List> 
    <Record> 
     <field1337>foo</field1337> 
     <field2>bar</field2> 
     <field3>baz</field3> 
    </Record> 
    </Record-List> 
</Root> 

當然映射文件可適於根據你的需求,我主要試圖表明樣品從所述映射文件的第二樣式表然後被施加到一個輸入樣本。

+0

好的解決方案。有很多這樣的情況,適合將輸入數據視爲定義一組轉換規則,可以使用XSLT本身將其轉換爲XSLT轉換規則。 –

+0

這是一個很棒的解決方案,謝謝! –

1

馬丁的解決方案是一個很好的,因爲這種方法是非常強大的,可擴展的,但它也可以解決更直接的問題:

<xsl:key name="mappings" match="mr:mapping-rules/field" use="@src"/> 

<xsl:template match="*"> 
    <xsl:element name="{(key('mappings', name())/@dest, name())[1]}"> 
    <xsl:copy-of select="@*"/> 
    <xsl:apply-templates/> 
    <xsl:element> 
</xsl:template> 
+0

這是解決此問題的較短途徑。但我想我會使用上面更靈活的解決方案。儘管如此,謝謝你的回覆! –