2011-09-05 58 views
7

问题是使用XSL合并和排序多个XML文件并输出有效的HTML,可用Firefox> = 3.5查看,如果可能的话IE> = 7。答案应该尽可能简单(性能不重要)。使用XSL合并和排序多个XML文件

文件A.XML

<?xml version="1.0"?> 
<root> 
    <tag>cc</tag> 
    <tag>aa</tag> 
</root> 

文件B.XML

<?xml version="1.0"?> 
<root> 
    <tag>xx</tag> 
    <tag>bb</tag> 
</root> 

文件INDEX.XML

<?xml version="1.0"?> 
<?xml-stylesheet type="text/xsl" href="merge.xslt"?> 
<list> 
    <entry>a.xml</entry> 
    <entry>b.xml</entry> 
</list> 

文件merge.xslt

<?xml version="1.0"?> 
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:ph="http://ananas.org/2003/tips/photo"> 

    <xsl:output method="html"/> 

    <xsl:template match="list"> 
     <html> 
      <body> 
       <xsl:apply-templates/> 
      </body> 
     </html> 
    </xsl:template> 

    <xsl:template match="entry"> 
     <xsl:for-each select="document(.)/root/tag"> 
      <!-- This will only sort the values of a single file --> 
      <xsl:sort select="." data-type="text" order="ascending" /> 
      - <xsl:value-of select="."/> <br/> 
     </xsl:for-each> 
    </xsl:template> 
</xsl:stylesheet> 

电流输出:

  • AA

  • 立方厘米

  • BB

  • XX

预期输出:

  • AA

  • BB

  • 立方厘米

  • XX

+1

好问题,+1。看到我的答案是一个完整的,非常简短的解决方案,没有任何其他答案的复杂性:没有扩展功能,没有变量,没有'xsl:for-each' ...... –

+0

还添加了大量的解释。 –

回答

8

对此的解决方案是非常短的并且容易变换(绝对没有扩展功能a再需要):

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

<xsl:template match="/*"> 
    <html> 
    <ul> 
    <xsl:apply-templates 
     select="document(entry)/*/tag"> 
     <xsl:sort/> 
    </xsl:apply-templates> 
    </ul> 
    </html> 
</xsl:template> 

<xsl:template match="tag"> 
    <li><xsl:value-of select="."/></li> 
</xsl:template> 
</xsl:stylesheet> 

当这种转化应用所提供的指数。XML文件

<list> 
    <entry>a.xml</entry> 
    <entry>b.xml</entry> 
</list> 

想要的,正确的结果产生

<html> 
    <ul> 
     <li>aa</li> 
     <li>bb</li> 
     <li>cc</li> 
     <li>xx</li> 
    </ul> 
</html> 

,它显示在任何浏览器

  • AA
  • BB
  • 立方厘米
  • XX

说明该解决方案使用标准的XSLT功能document()的功率。如W3C XSLT 1.0建议书所定义:

当文档函数有且只有一个参数和参数 是一个节点集合,那么结果是工会,在 参数的每个节点节点 - 设置调用文件的功能与 的第一个参数是一个节点的字串值的结果,

这说明我们的代码这个片段的效果:

<xsl:apply-templates 
    select="document(entry)/*/tag"> 
    <xsl:sort/> 
</xsl:apply-templates> 

这里发生的是document()函数的参数是index.xml顶部元素的所有entry子元素的节点集。结果是所有文档节点的联合。

因此

select="document(entry)/*/tag" 

选择在index.xml参考的所有文件都tag元素。然后对它们进行排序(按xsl:sort),并且已排序的节点列表中的每个元素都由匹配tag的模板处理。

+0

已接受,因为答案有效且易于理解。非常好的解释! – gaddomn

+1

我不知道为什么我这么复杂。我需要休息一会儿。最佳和简单的方法+1。 –

+0

@gaddomn:不客气。 @_empo:你也是。 –