Мне интересно, позволяет ли XSLT сортировать XML-файл, если я не знаю всей XML-схемы.
Например, я хотел бы отсортировать следующий XML-файл.
Сортировать / CATALOG / CD элементы по / CATALOG / CD / TITLE
<CATALOG attrib1="value1">
<DVD2>
<TITLE>The Godfather2</TITLE>
</DVD2>
<CD>
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
<CD attrib4="value4">
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>
<CATALOG>
<CD><TITLE>E</TITLE></CD>
<CD><TITLE>I</TITLE></CD>
<CD><TITLE>D</TITLE></CD>
</CATALOG>
</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD attrib2="value2">
<TITLE attrib3="value3">Greatest Hits</TITLE>
<ARTIST>Dolly Parton</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>RCA</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1982</YEAR>
</CD>
<DVD>
<TITLE>The Godfather1</TITLE>
</DVD>
</CATALOG>
Вывод должен быть:
<CATALOG attrib1="value1">
<CD attrib4="value4">
<TITLE>Empire Burlesque</TITLE>
<ARTIST>Bob Dylan</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>Columbia</COMPANY>
<PRICE>
<CATALOG>
<CD><TITLE>E</TITLE></CD>
<CD><TITLE>I</TITLE></CD>
<CD><TITLE>D</TITLE></CD>
</CATALOG>
</PRICE>
<YEAR>1985</YEAR>
</CD>
<CD attrib2="value2">
<TITLE attrib3="value3">Greatest Hits</TITLE>
<ARTIST>Dolly Parton</ARTIST>
<COUNTRY>USA</COUNTRY>
<COMPANY>RCA</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1982</YEAR>
</CD>
<CD>
<TITLE>Hide your heart</TITLE>
<ARTIST>Bonnie Tyler</ARTIST>
<COUNTRY>UK</COUNTRY>
<COMPANY>CBS Records</COMPANY>
<PRICE>9.90</PRICE>
<YEAR>1988</YEAR>
</CD>
<DVD2>
<TITLE>The Godfather2</TITLE>
</DVD2>
<DVD>
<TITLE>The Godfather1</TITLE>
</DVD>
</CATALOG>
Вот одна из многих попыток, которые я сделал:
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<!--<CATALOG>-->
<xsl:for-each select="CATALOG/CD">
<xsl:sort select="TITLE" />
<xsl:copy-of select="."/>
</xsl:for-each>
<!--</CATALOG>-->
</xsl:template>
</xsl:stylesheet>
Проблема в том, что с этим XSLT части XML вне списка CD не отображаются.
Я мог бы раскомментировать две закомментированные части кода, но это именно то, чего я хочу избежать.
В этом случае, если к элементу CATALOG будут добавлены какие-либо атрибуты, они не будут скопированы в выходной XML.
Я не хочу перестраивать файл XML: я просто хочу сделать сортировку, зная точную информацию только о некоторой части XML-схемы.
Эту функцию легко реализовать, например, используя .NET (с объектами XmlDocument и XmlNode) или библиотеку Python lxmx, но возможно ли это с XSLT?
Спасибо!
Примечание. Нелегко найти образец входного XML, который позволит избежать неправильного понимания вопроса во всех случаях. Но я постараюсь максимально подробно описать проблему:
- должны быть отсортированы только элементы CD прямо под CATALOG (например, элементы CD в разделе Боба Дилана должны быть оставлены нетронутыми)
- все равно, находятся ли элементы, кроме CD (например, DVD и DVD2), в начале или конце списка
- без элементов, атрибутов, значений, комментариев, поэтому в выходном XML ничего не должно быть пропущено
- не-CD элементы (например, DVD и DVD2) не должны сортироваться подэлементом TITLE