Множественная замена XSL в строке преобразования - PullRequest
0 голосов
/ 29 ноября 2018

Я пытаюсь преобразовать атрибуты в узел и заменить значения, чтобы исправить один.Преобразование и объединение работает хорошо, но я не могу понять, как заменить преобразованные данные.Я попытался choose и перебрать атрибуты без результата.

Вот исходный XML

<cats>
  <cat id="11">Foo 1</cat>
  <cat id="12">Foo 2</cat>
</cats>

Мой XLS - эта часть работает

<xsl:template match="cats">
    <cat-id>
       <xsl:value-of select="string-join(cat/@id, ',')" />
     </cat-id>
</xsl:template>

Таблица замены 11 => 24, 12 => 75, 13 => 145 ...

Результат, которого я хочу достичь

<cat-id>24,75</cat-id>

Ответы [ 2 ]

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

Вот как вы можете сделать это в XSLT 1.0 :

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:my="http://www.example.com/my"
exclude-result-prefixes="my">
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<my:replacement-map>
    <value key="11">24</value>
    <value key="12">75</value>
    <value key="13">145</value>
</my:replacement-map>

<xsl:template match="cats">
    <cat-id>
        <xsl:for-each select="cat">
            <xsl:value-of select="document('')/xsl:stylesheet/my:replacement-map/value[@key=current()/@id]" />
            <xsl:if test="position() != last()">
                <xsl:text>,</xsl:text>
            </xsl:if>
        </xsl:for-each>
    </cat-id>
</xsl:template>

</xsl:stylesheet>

Если у вас много значений, это можно сделать немного более эффективным с помощью клавиши,Но указывать ключ на другой документ (в данном случае саму таблицу стилей XSLT) неудобно в XSLT 1.0.

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

Вы можете написать функцию, которая сопоставляет каждое значение атрибута id с его заменой, в XSLT 3 (поддерживается с 2017 года Saxon 9.8 и более поздними версиями и Altova 2017 и более поздними версиями) вы можете использовать map в качестве функции:

<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:param name="replacement-map" as="map(xs:integer, xs:integer)" select="map { 11 : 24, 12 : 75, 13 : 145 }"/>

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:template match="cats">
        <cat-id>
           <xsl:value-of select="cat/@id/$replacement-map(xs:integer(.))" separator="," />
         </cat-id>
    </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / jyH9rNs

В XSLT 2 вы можете использовать структуру XML для представления вашей таблицы / карты замены и использовать ключ для поисказамена для значения атрибута:

<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:param name="replacement-map">
        <value key="11">24</value>
        <value key="12">75</value>
        <value key="13">145</value>
    </xsl:param>

    <xsl:key name="rep" match="value" use="@key"/>

    <xsl:mode on-no-match="shallow-copy"/>

    <xsl:template match="cats">
        <cat-id>
           <xsl:value-of select="cat/@id/key('rep', ., $replacement-map)" separator="," />
         </cat-id>
    </xsl:template>

</xsl:stylesheet>

https://xsltfiddle.liberty -development.net / jyH9rNs / 1

Наконец, в XSLT 1, так как функция key неу вас нет третьего параметра для изменения контекста, вы можете использовать

<xsl:stylesheet
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:exsl="http://exslt.org/common"
    xmlns:msxml="urn:schemas-microsoft-com:xslt"
    exclude-result-prefixes="exsl msxml"
    version="1.0">

  <xsl:param name="replacement-map-rtf">
    <value key="11">24</value>
    <value key="12">75</value>
    <value key="13">145</value>
  </xsl:param>

  <xsl:param name="replacement-map" select="exsl:node-set($replacement-map-rtf)"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:key name="rep" match="value" use="@key"/>

  <xsl:template match="cats">
      <cat-id>
          <xsl:apply-templates select="cat/@id"/>
      </cat-id>
  </xsl:template>

  <xsl:template match="cat/@id">
      <xsl:if test="position() > 1">,</xsl:if>
      <xsl:variable name="this" select="."/>
      <xsl:for-each select="$replacement-map">
          <xsl:value-of select="key('rep', $this)"/>
      </xsl:for-each>
  </xsl:template>

</xsl:stylesheet>

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

...