使用XSLT转换XML文件

问题描述:

我想通过XSLT将给定的XML文件(它是RelaxNG语法)转换为其他语言。假设XML文件是:使用XSLT转换XML文件

<?xml version="1.0" encoding="UTF-8"?> 
<grammar> 
    <element name="table" /> 
    <element name="chair" /> 
</grammar> 

现在,我想与像

en=table, de=Tisch, fr=table 
en=chair, de=Stuhl, fr=chaise 
... (there will be many, many more entries) 

但是我也可以把这些信息在外部文件中的信息的XSLT样式表(我从开始刮)。你可以给我建议如何制定一个XSLT?我正在考虑为此使用<xsl:key>,但我从来没有在XSLT中获得密钥的悬挂。结果应该是这样的,当我创建德语翻译:

<?xml version="1.0" encoding="UTF-8"?> 
<grammar lang="de"> 
    <element name="Tisch" /> 
    <element name="Stuhl" /> 
</grammar> 

这种转变

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
<xsl:output omit-xml-declaration="yes" indent="yes"/> 
<xsl:strip-space elements="*"/> 

<xsl:param name="pFrom" select="'en'"/> 
<xsl:param name="pTo" select="'de'"/> 

<xsl:key name="kIdByLangVal" match="@dId" 
    use="concat(../../@lang, '+', ../@value)"/> 

<xsl:key name="kValByLangId" match="@value" 
    use="concat(../../@lang, '+', ../@dId)"/> 

<xsl:variable name="vDicts" select= 
    "document('file:///c:/temp/delete/dicts.xml')"/> 

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

<xsl:template match="@name"> 
    <xsl:variable name="vCur" select="."/> 

    <xsl:attribute name="name"> 
    <xsl:for-each select="$vDicts"> 
    <xsl:value-of select= 
    "key('kValByLangId', 
      concat($pTo, '+', 
       key('kIdByLangVal', 
        concat($pFrom, '+', $vCur) 
        ) 
       ) 
     ) 
    "/> 
    </xsl:for-each> 
    </xsl:attribute> 
</xsl:template> 
</xsl:stylesheet> 

时所提供的XML文档应用:

<grammar> 
    <element name="table" /> 
    <element name="chair" /> 
</grammar> 

并将文件C:\temp\delete\dicts.xml设为

<dictionaries> 
<dictionary lang="en"> 
    <word dId="1" value="table"/> 
    <word dId="2" value="chair"/> 
</dictionary> 
<dictionary lang="de"> 
    <word dId="1" value="Tisch"/> 
    <word dId="2" value="Stuhl"/> 
</dictionary> 
</dictionaries> 

产生想要的,正确的结果

<grammar> 
    <element name="Tisch"/> 
    <element name="Stuhl"/> 
</grammar> 
+0

方式XSL样式表看起来总是吓唬魂飞魄散了我。 ;) – DanMan

+2

@DanMan:什么让我害怕*是一种必须的,类似意大利面的代码:) –

+0

首先:谢谢Dimitre,你总是发布很棒的答案!目前我对长字典不太满意(当我有100个条目时,很难看到什么是正确的数字)。我应该事先考虑过这个。我现在正在玩你的解决方案,并尝试将它应用到具有以下样式的字典中:'。 – topskip