Соответствие XSLT и сортировка с внешним списком, сохраненным в файле XML - PullRequest
0 голосов
/ 13 ноября 2018

Привет всем StackOverFlowers,

Я наткнулся на большую неразрешимую проблему, пытаясь отсортировать мой XML. У меня есть набор данных XML, сформулированный как ниже;

<root>
  <node code="text1"> ... </node>
  <node code="text2"> ... </node>
  <node code="text3"> ... </node>
  <node code="textX"> ... </node>
</root>

Теперь я хочу отсортировать его по атрибуту кода и хотел бы сохранить список атрибутов кода, отсортированный во внешнем файле SORT.XML. Атрибуты кода будут отсортированы и сохранены в SORT.XML примерно так (одна строка, один атрибут);

textX
text2
text1
text3

... и так далее ...

После обработки OUTPUT.XML будет выглядеть так:

<root>
  <node code="textX"> ... </node>
  <node code="text2"> ... </node>
  <node code="text1"> ... </node>
  <node code="text3"> ... </node>
</root>

Я действительно застрял, и понятия не имею, как продолжить / решить эту проблему с помощью XSLT?

Спасибо за вашу помощь!

Делука

1 Ответ

0 голосов
/ 14 ноября 2018

Если вам необходимо использовать описанный вами формат файла «одна строка на код», то анализ кодов немного сложен в 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>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...