Попытка распечатать значения узлов в XSLT, используя имена переменных элементов - PullRequest
0 голосов
/ 09 ноября 2011

Итак, вот проблема, которая беспокоила меня последние несколько дней. Это должно быть довольно легко, но отладка XSLT - это просто такая боль. Мы используем Xalan 1.0 на Java 1.6

Входной XML

<?xml version="1.0" encoding="UTF-8"?>
<rfb2>
    <rfb2_item>
        <VALDATE>2011-10-23</VALDATE>
        <FUND_ID>300</FUND_ID>
        <SEC_ID>34567</SEC_ID>
    </rfb2_item>
    <rfb2_item>
        <VALDATE>2011-1-09</VALDATE>
        <FUND_ID>700</FUND_ID>
        <SEC_ID>13587</SEC_ID>
    </rfb2_item>
    <rfb2_item>
        <VALDATE>2011-3-09</VALDATE>
        <FUND_ID>200</FUND_ID>
        <SEC_ID>999334</SEC_ID>
    </rfb2_item>
<rfb2>

Нам нужно преобразовать XML в список значений через запятую для каждого rfb2_item, поэтому таблица стилей всегда повторяет узлы rfb2_item. Мы используем параметр в таблице стилей, чтобы контролировать, какие элементы rfb2_item (valdate, fund_id, sec_id) будут выводиться и в каком порядке, например

<xsl:param name="$outputElements" select="'VALDATE,FUND_ID'"/>
..outputs...

2011-10-23,300
2011-1-09,700
2011-3-09,200



<xsl:param name="$outputElements" select="'SEC_ID'"/>    
..outputs...

34567
13587
999334

Особый случай, когда, если $ outputElements равен '*', просто выведите элементы в том порядке, в котором они отображаются во входных данных xml

<xsl:param name="$outputElements" select="'*'"/>

..outputs...

2011-10-23,300,34567
2011-1-09,700,13587
2011-3-09,200,999334

Итак, мой вопрос: как нам написать шаблон для создания желаемого результата на основе параметра $ outputElements? Рабочий пример был бы великолепен ...

Ответы [ 2 ]

1 голос
/ 09 ноября 2011

Да, FailedDev прав.Кто-то написал бы это для вас:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output method="text" />

    <xsl:param name="outputElements" select=" 'FUND_ID,SEC_ID,VALDATE' " />

    <xsl:template match="rfb2_item">

        <xsl:for-each select="*[contains($outputElements, local-name()) or $outputElements = '*']">
            <xsl:sort select="string-length(substring-before($outputElements, local-name(.)))" />
            <xsl:value-of select="text()" />
            <xsl:if test="position() != last()">
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
        <xsl:text>&#13;&#10;</xsl:text>

    </xsl:template>

</xsl:stylesheet>

Бит объяснения.xsl:for-each выберет каждый элемент в текущем rfb2_item, для которого локальное имя содержится в параметре outputElements, или для которого параметр outputElements равен * (который всегда будет иметь значение true, если этодело).Затем он будет сортировать те, которые основаны на длине подстроки, которая идет перед этим локальным именем в outputElements.Так как это значение становится больше, когда имя встречается позже в этом параметре, это приводит к упорядочению на основе вашего параметра.

Пример: элемент VALDATE даст FUND_ID,SEC_ID для функции substring-before, которая, в свою очередь,даст 14 в качестве длины строки.Это больше, чем 8, которое вы получите за SEC_ID, то есть значение VALDATE упорядочено после SEC_ID.

После xsl:sort мы просто используем xsl:value-of длявыведите значение элемента.Вы могли бы хотеть урезать посторонние пробелы там.Наконец, мы проверяем, не совпадает ли позиция с последним узлом в текущем контексте (то есть xsl:for-each после сортировки ), и, если да, выводим запятую.Это позволяет избежать вывода запятой после последнего значения.

Разрыв строки, который я вставил с использованием xsl:text, предполагает соглашение Windows / DOS.Удалите &#13;, если файл должен использовать только символы новой строки для разрыва строки, вместо возврата каретки + новой строки.

Обратите внимание, что в выводе CSV это не может быть запятыми!Я оставлю это на ваше усмотрение.Было бы интересно изучить использование функций расширения для делегирования этой задачи Java, если это окажется слишком сложным в XSLT / XPath.

0 голосов
/ 10 ноября 2011

Иногда в такой ситуации стоит посмотреть на возможность создания или изменения кода XSLT с использованием XSLT. Таким образом, вы можете продвинуться дальше в параметризации - например, контролировать, какие поля выводятся, как они сортируются, сгруппированы ли они, критерии выбора, для которых выбираются строки и т. Д. И т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...