Если вам необходимо использовать описанный вами формат файла «одна строка на код», то анализ кодов немного сложен в XSLT 1. Это относительно просто в XSLT 2. Просто включите файл и используйте tokenize
функция:
Примечание: если в ваших кодах есть символы разметки, такие как <
и &
, вам нужно их экранировать.
<!DOCTYPE xsl:stylesheet [
<!ENTITY codes SYSTEM "sort.txt">
]>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:sort="urn:sort">
<!-- Include the ordered list of codes. -->
<sort:order>&codes;</sort:order>
<!-- This key is used to select the nodes to output -->
<xsl:key name="node-key" match="node" use="@code"/>
<xsl:template match="/root">
<xsl:copy>
<xsl:variable name="root" select="."/>
<!-- For each code in the list, output the nodes with matching code attributes -->
<xsl:for-each select="tokenize(document('')/*/sort:order, '\s+')">
<xsl:copy-of select="key('node-key', ., $root)"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Токенизация строк в XSLT 1 уродлива, но если вы отформатируете свой список кодов как XML, вам не придется это делать.
С вашими кодами, отформатированными так:
<codes>
<code>textX</code>
<code>text2</code>
<code>text1</code>
<code>text3</code>
</codes>
Вы можете запустить сортировку в XSLT 1:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/root">
<xsl:copy>
<xsl:variable name="root" select="."/>
<xsl:for-each select="document('sort.xml')/codes/code">
<xsl:copy-of select="$root/node[@code=current()]"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>