Сложный XSLT раскол? - PullRequest
       41

Сложный XSLT раскол?

5 голосов
/ 14 сентября 2009

Возможно ли разделить тег по границам от нижнего до верхнего регистра, т.е. например, тег 'UserLicenseCode' должен быть преобразован в 'User License Code' так что заголовки столбцов выглядят немного лучше.

Я делал что-то подобное в прошлом, используя регулярные выражения Perl, но XSLT для меня совершенно новая игра с мячом.

Буду признателен за любые указания по созданию такого шаблона!

Спасибо Кришна

Ответы [ 2 ]

2 голосов
/ 14 сентября 2009

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

Это был бы твой указатель. Мне понадобится некоторое время, чтобы разработать шаблон. :-) <ч /> Потребовалось некоторое тестирование, особенно чтобы получить пространство внутри всего. (Я неправильно использовал символ для этого!) Но этот код должен дать вам представление ...

Я использовал этот XML:

<?xml version="1.0" encoding="UTF-8"?>
<blah>UserLicenseCode</blah>

, а затем эта таблица стилей:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fo="http://www.w3.org/1999/XSL/Format">
    <xsl:output method="text"/>
    <xsl:variable name="Space">*</xsl:variable>
    <xsl:template match="blah">
    <xsl:variable name="Split">
        <xsl:call-template name="Split">
            <xsl:with-param name="Value" select="."/>
            <xsl:with-param name="First" select="true()"/>
        </xsl:call-template></xsl:variable>
        <xsl:value-of select="translate($Split, '*', ' ')" />
    </xsl:template>
    <xsl:template name="Split">
        <xsl:param name="Value"/>
        <xsl:param name="First" select="false()"/>
        <xsl:if test="$Value!=''">
            <xsl:variable name="FirstChar" select="substring($Value, 1, 1)"/>
            <xsl:variable name="Rest" select="substring-after($Value, $FirstChar)"/>
                <xsl:if test="not($First)">
                    <xsl:if test="translate($FirstChar, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', '..........................')= '.'">
                        <xsl:value-of select="$Space"/>
                    </xsl:if>
                </xsl:if>
                <xsl:value-of select="$FirstChar"/>
                <xsl:call-template name="Split">
                    <xsl:with-param name="Value" select="$Rest"/>
                </xsl:call-template>
        </xsl:if>
    </xsl:template>
</xsl:stylesheet>

и я получил это как результат:

User License Code

Имейте в виду, что пробелы и другие пробельные символы обычно удаляются из XML, поэтому вместо этого я использовал '*', который я перевел в пробел.

Конечно, этот код можно улучшить. Это то, что я мог придумать за 10 минут работы. В других языках это заняло бы меньше строк кода, но в XSLT это все еще довольно быстро, учитывая количество строк кода, которые он содержит.

1 голос
/ 14 сентября 2009

Решение XSLT + FXSL (в XSLT 2.0, но почти тот же код будет работать с XSLT 1.0 и FXSL 1.x :

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:f="http://fxsl.sf.net/"
xmlns:testmap="testmap"
exclude-result-prefixes="f testmap"
>
   <xsl:import href="../f/func-str-dvc-map.xsl"/>
   <testmap:testmap/>

   <xsl:output omit-xml-declaration="yes" indent="yes"/>

   <xsl:template match="/">
     <xsl:variable name="vTestMap" select="document('')/*/testmap:*[1]"/>

     '<xsl:value-of select="f:str-map($vTestMap, 'UserLicenseCode')"
       />'
   </xsl:template>

    <xsl:template name="mySplit" match="*[namespace-uri() = 'testmap']"
     mode="f:FXSL">
      <xsl:param name="arg1"/>

      <xsl:value-of select=
       "if(lower-case($arg1) ne $arg1)
         then concat(' ', $arg1)
         else $arg1
       "/>
    </xsl:template>
</xsl:stylesheet>

Когда указанное преобразование применяется к любому исходному документу XML (не используется), получается ожидаемый правильный результат:

'Код лицензии пользователя'

Примечание :

  1. Мы используем DVC-версию функции / шаблона FXSL str-map(). Это функция высшего порядка (HOF), которая принимает два аргумента: другую функцию и строку. str-map() применяет функцию к каждому символу строки и возвращает объединение результатов.

  2. Поскольку используется функция нижнего регистра () (в версии XSLT 2.0), мы не ограничены только латинским алфавитом.

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