Вопрос

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

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

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

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

Это было полезно?

Решение

Используя рекурсию, можно пройти по строке в 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 это все еще довольно быстро, учитывая количество содержащихся в нем строк кода.

Другие советы

Решение 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), мы не ограничены только латинским алфавитом.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top