Объединение и сортировка нескольких XML-файлов с помощью XSL
проблема заключается в объединении и сортировке нескольких XML-файлов с XSL и выводе допустимого 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
cc
bb
xx
ожидаемый результат:
aa
bb
cc
xx
1 ответов
решение этой проблемы-очень короткое и простое преобразование (абсолютно нет функции расширения!):
<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
- cc
- xx
объяснение: это решение использует мощность стандартной функции XSLT document()
. как определено в рекомендации W3C XSLT 1.0:
когда функция документа есть ровно один аргумент и аргумент является набором узлов, то результатом является объединение для каждого узла в аргумент node-set, результата вызова функции документа с помощью первым аргументом является строковое значение node
это объясняет эффект этого фрагмента из нашего кода:
<xsl:apply-templates
select="document(entry)/*/tag">
<xsl:sort/>
</xsl:apply-templates>
здесь происходит то, что аргумент document()
функция-это набор узлов всех entry
дети верхнего элемента index.xml
. Результатом является объединение всего документа узлы.
:
select="document(entry)/*/tag"
выбирает все tag
элементы во всех документах, упомянутых в index.xml
. Затем они сортируются (по xsl:sort
) и каждый из элементов уже отсортированного списка узлов обрабатывается шаблоном matching tag
.