xml - 使用 XSL 合并和排序多个 XML 文件

标签 xml xslt sorting merge

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

文件 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>

文件合并.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

最佳答案

这个问题的解决方案是一个非常简短和容易的转换(绝对不需要扩展函数!):

<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>

当此转换应用于提供的 index.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>

它在任何浏览器中显示为:

  • 一个
  • bb
  • 抄送
  • xx

说明:此解决方案使用标准 XSLT 函数的强大功能 document() . 如 W3C XSLT 1.0 Recommendation 中所定义:

When the document function has exactly one argument and the argument is a node-set, then the result is the union, for each node in the argument node-set, of the result of calling the document function with the first argument being the string-value of the node

这解释了我们代码中这个片段的效果:

<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 的模板进行处理。

关于xml - 使用 XSL 合并和排序多个 XML 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7312893/

相关文章:

android - android布局中的错误定位

java - XSLT 解析包含转义字符和非转义字符(< 和 <)的字符串

xml - xslt分组问题

html - 尝试使用 XSLT 2.0 在 HTML &lt;style&gt; 元素中嵌入包含 '>' 子选择器的 CSS

java - 如何根据与另一个给定字符串的相似性对包含 1000 多个不同字符串的 ArrayList 进行排序

c++ - 使用 QIODevice::write 方法添加 "&#xd; "而不是回车

xml - xslt 结果文档覆盖或跳过具有重复 uri 的文件

java - 为什么在排序数组的二分查找场景中仍然出现错误情况?

macos - 以编程方式对 NSTableView 进行排序

android - 如何阻止 IDE 在我的非 Windows 项目中引用特定于 Windows 的 XML 单元?