XSLT 3.0 - заменить числовые символы числовыми представлениями - PullRequest
0 голосов
/ 09 ноября 2019

Я пытаюсь использовать xslt для создания набора данных xml, и в настоящее время сталкиваюсь с проблемой, что пытаюсь установить некоторые недопустимые имена элементов, 3RD_RACK, 3DATA_VIEW, и то, что я пытался использовать:

<xsl:value-of select="translate(current()/@name), translate(current()/@name), 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_', ''), '_')"/>

, который заменяет 3RD_RACK -> _RD_RACK

и все другие числа в наборе данных, такие как:

PROGRAMMDAUERPROGRAM1 -> PROGRAMMDAUERPROGRAM
ENERGY_CLASS_2010 -> ENERGY_CLASS__

Мне пришло в голову заменить все числа их строковыми представлениямичтобы присоединиться к проверке XML, такой как:

1 -> один 2 -> два

Так что в итоге мой ввод становится:

3RD_RACK -> threeRD_RACK, ENERGY_CLASS_twozeroonezero, PROGRAMMDAUERPROGRAMone

Но я не мог 'я не могу достичь своей цели, пытаясь:

    <xsl:variable name="MyMap" select="
            map { 
            '1' : 'one', 
            '2' : 'two',
            '3' : 'three',
            '4' : 'four',
            '5' : 'five',
            '6' : 'six', 
            '7' : 'seven',
            '8' : 'eight',
            '9' : 'nine'}">
        </xsl:variable>

<xsl:value-of select="$MyMap(current()/@name)"/>

возвращает только цифры, поэтому кто-то может мне помочь, как я могу перевести только числа, встречающиеся в строке?

Заранее спасибо за ваши ответы.

Ответы [ 2 ]

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

Простым решением было бы закодировать цифры, используя другие символы. Тогда вы можете сделать что-то вроде:

<xsl:element name="{translate(@name, '1234567890', 'αβγδεζηθικλμνξο')}">
    <xsl:apply-templates/>
</xsl:element>

Это дает еще одно преимущество - возможность восстановить исходное имя (при условии, что оно не содержит символов, использованных для замены). Используя ваш метод, невозможно определить, был ли оригинал "1d" или "oned".


. Обратите внимание также, что ваш метод может быть реализован в старомодном способе XSLT 1.0:

<xsl:variable name="name">
    <xsl:variable name="char1" select="substring(@name, 1, 1)"/>
    <xsl:choose>
        <xsl:when test="$char1='0'">zero</xsl:when>
        <xsl:when test="$char1='1'">one</xsl:when>
        <xsl:when test="$char1='2'">two</xsl:when>
        <xsl:when test="$char1='3'">three</xsl:when>
        <xsl:when test="$char1='4'">four</xsl:when>
        <xsl:when test="$char1='5'">five</xsl:when>
        <xsl:when test="$char1='6'">six</xsl:when>
        <xsl:when test="$char1='7'">seven</xsl:when>
        <xsl:when test="$char1='8'">eight</xsl:when>
        <xsl:when test="$char1='9'">nine</xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$char1"/>
        </xsl:otherwise>
    </xsl:choose>
    <xsl:value-of select="substring(@name, 2)"/>
</xsl:variable>
<xsl:element name="{$name}">
    <xsl:apply-templates/>
</xsl:element>

Это не кажется намного более многословным, чем XSLT 3.0.


Добавлено:

Я забыл упомянуть самую важную вещь: тамЕсть и другие способы, которыми строка может не соответствовать спецификации имени XML . Если вы не можете быть уверены в том, что указанное имя является допустимым именем элемента XML, наиболее подходящим вариантом будет:

<elem name="{@name}">
   <xsl:apply-templates/>
</elem>

Это самое простое и в то же время самое безопасное решение.

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

Вот пример, который использует функцию analyze-string из XPath 3 для замены любой цифры ASCII на имя из карты:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="#all"
    version="3.0">

  <xsl:output method="text"/>

  <xsl:variable name="MyMap" select="
            map { 
            '0' : 'zero',
            '1' : 'one', 
            '2' : 'two',
            '3' : 'three',
            '4' : 'four',
            '5' : 'five',
            '6' : 'six', 
            '7' : 'seven',
            '8' : 'eight',
            '9' : 'nine'}">
        </xsl:variable>

  <xsl:param name="names"
    as="xs:string*"
    select="'3RD_RACK', 'ENERGY_CLASS_2010', 'PROGRAMMDAUERPROGRAM1'"/>

  <xsl:variable name="converted-names"
    as="xs:string*"
    select="$names ! string-join(analyze-string(., '[0-9]')/*/(if (self::*:match) then $MyMap(.) else string()))"/>

  <xsl:template match="/">
      <xsl:value-of 
        select="$converted-names" separator="&#10;"/>
  </xsl:template>

</xsl:stylesheet>

Вывод:

threeRD_RACK
ENERGY_CLASS_twozeroonezero
PROGRAMMDAUERPROGRAMone

https://xsltfiddle.liberty -development.net / pPJ8LVj / 2

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