2016-02-06 25 views
0

我想学习xslt作为一种兴趣,而我感兴趣的用例之一就是将某些组件的定义扩展到其完整形式。一个例子应该澄清我的意思。例如如果我的输入XML的样子:使用xslt扩展compact xml表示形式到更详细的表示形式

<universe> 
    <galaxies> 
     <galaxy name="milky way"> 
      <system name="solar system"/> 
     </galaxy> 
     <galaxy name="lactose free"> 
      <system name="windmill system"/> 
     </galaxy> 
     <galaxy name="parallelish solar system"> 
      <system name="the earth system"/> 
     </galaxy> 
    </galaxies> 
    <systems> 
     <system name="solar system"> 
      <planet name="pluto"/> 
      <system name="the earth system"/> 
      <planet name="mercury"/> 
     </system> 
     <system name="windmill system"> 
      <planet name="windy"/> 
     </system> 
     <system name="the earth system"> 
      <planet name="earth"/> 
      <satellite name="moon"/> 
     </system> 
    </systems> 
</universe> 

我的XML输出会在星系的定义扩大递归这些系统定义(例如,在太阳系中地球系统)和定义出现的每一个地方(如地球系统发生在两个不同的系统中)。该系统部分将被删除:

<universe> 
    <galaxies> 
     <galaxy name="milky way"> 
      <system name="solar system"> 
       <planet name="pluto"/> 
       <system name="the earth system"> 
        <planet name="earth"/> 
        <satellite name="moon"/> 
       </system> 
       <planet name="mercury"/> 
      </system> 
     </galaxy> 
     <galaxy name="lactose free"> 
      <system name="windmill system"> 
       <planet name="windy"/> 
      </system> 
     </galaxy> 
     <galaxy name="parallelish solar system"> 
      <system name="the earth system"> 
       <planet name="earth"/> 
       <satellite name="moon"/> 
      </system> 
     </galaxy> 
    </galaxies> 
</universe> 

我非常新XSLT和截至目前,我已经按照思想的线已经以某种方式定义这些组件块变量和将它们插入(第二场)合格。但是,正如我搜索一下并阅读了一些试图找到示例的内容,我一直没有取得成功。我想知道这是否可能(我期望如此),以及我需要使用什么概念来实现这一点。示例代码片段会非常有帮助。

谢谢!

回答

0

XSLT有一个非常有用的keys解决交叉引用的机制。为了演示它如何工作的,我第一次修改您的XML例子,以避免循环引用:

XML

<universe> 
    <galaxies> 
     <galaxy name="milky way"> 
      <system-ref name="solar system"/> 
     </galaxy> 
     <galaxy name="lactose free"> 
      <system-ref name="windmill system"/> 
     </galaxy> 
     <galaxy name="parallelish solar system"> 
      <system-ref name="the earth system"/> 
     </galaxy> 
    </galaxies> 
    <systems> 
     <system name="solar system"> 
      <planet name="pluto"/> 
      <system-ref name="the earth system"/> 
      <planet name="mercury"/> 
     </system> 
     <system name="windmill system"> 
      <planet name="windy"/> 
     </system> 
     <system name="the earth system"> 
      <planet name="earth"/> 
      <satellite name="moon"/> 
     </system> 
    </systems> 
</universe> 

XSLT

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

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

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

<xsl:template match="system-ref"> 
    <xsl:apply-templates select="key('system-by-name', @name)"/> 
</xsl:template> 

<xsl:template match="systems"/> 

</xsl:stylesheet> 

结果

<?xml version="1.0" encoding="UTF-8"?> 
<universe> 
    <galaxies> 
     <galaxy name="milky way"> 
     <system name="solar system"> 
      <planet name="pluto"/> 
      <system name="the earth system"> 
       <planet name="earth"/> 
       <satellite name="moon"/> 
      </system> 
      <planet name="mercury"/> 
     </system> 
     </galaxy> 
     <galaxy name="lactose free"> 
     <system name="windmill system"> 
      <planet name="windy"/> 
     </system> 
     </galaxy> 
     <galaxy name="parallelish solar system"> 
     <system name="the earth system"> 
      <planet name="earth"/> 
      <satellite name="moon"/> 
     </system> 
     </galaxy> 
    </galaxies> 
</universe> 
+0

谢谢你的帮助迈克尔!我现在开始阅读钥匙,谢谢你指出。 –

+0

我还发现,对于我的特殊情况,使用我发布的原始xml隐式区分系统/系统(定义)与系统引用,以及下面更具体的模板匹配会更自然: 阅读有关阅读排除比赛也是如此(例如不(系统/系统))。 –