XSLT: создание карты в XSLT - PullRequest
       0

XSLT: создание карты в XSLT

20 голосов
/ 02 сентября 2010

Я хочу иметь карту значения ключа в xsl и поэтому определил переменную, которая имеет фрагмент xml, но позже, когда я пытаюсь получить доступ к узлам xml в переменной, я получаю ошибку, что тип выражения xpath не может быть разрешен .

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="/">
        <xsl:variable name="map">
            <map>
                <entry key="key-1">value1</entry>
                <entry key="key-2">value2</entry>
                <entry key="key-3">value3</entry>
            </map>
        </xsl:variable>
        <output>
            <xsl:value-of select="$map/entry[@key='key-1']"/>
        </output>
    </xsl:template>
</xsl:stylesheet>

Ответы [ 3 ]

37 голосов
/ 02 сентября 2010

XSLT 2.0

Используя XSLT 2.0, работает следующее решение:

  <xsl:variable name="map">
    <entry key="key-1">value1</entry>
    <entry key="key-2">value2</entry>
    <entry key="key-3">value3</entry>
  </xsl:variable>

  <xsl:template match="/">
    <output>
      <xsl:value-of select="$map/entry[@key='key-1']"/>
    </output>
  </xsl:template>

XSLT 1.0

Нельзя использовать фрагмент дерева результатов в выражении XPath в XSLT1.0, но fn:document() может получить значения карты.Ответ на подобный вопрос будет работать здесь:.

<xsl:value-of select="document('')//xsl:variable[@name='map']/map/entry[@key='key-1']"/>

Как описано в спецификации XSLT 1.0 :

document('') относится к корневому узлу таблицы стилей;древовидное представление таблицы стилей точно такое же, как если бы XML-документ, содержащий таблицу стилей, был исходным исходным документом.

Однако вам не нужно использовать xsl:variable для этого.Вы можете указать свой узел карты непосредственно в xsl:stylesheet, но вы должны помнить, что элементы верхнего уровня должны иметь ненулевой URI пространства имен:

<xsl:stylesheet 
  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
  xmlns:my="some.uri" exclude-result-prefixes="my">

  <my:map>
    <entry key="key-1">value1</entry>
    <entry key="key-2">value2</entry>
    <entry key="key-3">value3</entry>
  </my:map>

  <xsl:template match="/">
    <output>
      <xsl:value-of select="document('')/*/my:map/entry[@key='key-1']"/>
    </output>
  </xsl:template>
</xsl:stylesheet>
6 голосов
/ 02 сентября 2010

Вы можете обойти XSLT 1.0 без поддержки использования содержимого переменной в качестве набора узлов.Вам придется полагаться на расширения, добавленные создателем парсера.Например, Microsoft предложила функцию для обхода этого: node-set ()

Ваш XSL будет выглядеть следующим образом:

<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt">
    <xsl:template match="/">
        <xsl:variable name="map">
            <map>
                <entry key="key-1">value1</entry>
                <entry key="key-2">value2</entry>
                <entry key="key-3">value3</entry>
            </map>
        </xsl:variable>
        <output>
            <xsl:value-of select="msxsl:node-set($map)/map/entry[@key='key-1']"/>
        </output>
    </xsl:template>
</xsl:stylesheet>

Обратите внимание на пространство имен и префикс msxsl здесь.Это будет работать только в приложениях, основанных на синтаксическом анализаторе Microsoft (например, Internet Explorer использует его, а также .NET).Другие парсеры могут иметь или не иметь такого расширения (например, у Saxxon, но оно немного по-другому).Но это исключает зависимость от XSLT 2.0, поскольку в XSLT 1.0 это будет нормально работать, и Microsoft еще не поддерживает XSLT 2.0 в своей библиотеке XML (если только они не добавили его недавно).

В зависимости от того, какой анализатор выВы используете, выше может работать хорошо для вас, в противном случае ответ Per T лучше для вас.

5 голосов
/ 13 июля 2012

В рабочем проекте XSLT 3.0 предлагается новый тип элемента (карты) XPath, см. карты в спецификации XSLT 3.0 WD Spec .

Итак, если ваш процессор XSLT поддерживает 3.0 и карты (например, Saxon 9.4), вы можете использовать следующий код:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:xs="http://www.w3.org/2001/XMLSchema" 
  exclude-result-prefixes="xs" 
  version="3.0">
  <xsl:output indent="yes"/>

  <xsl:template match="/">
    <xsl:variable name="map" select="
      map { 
      'key-1' := 'value1', 
      'key-2' := 'value2',
      'key-3' := 'value3' }">      
    </xsl:variable>
    <output>
      <xsl:value-of select="
        $map('key-1') || ', ' || $map('key-2') || ', ' || $map('key-3')"/> 
    </output>
  </xsl:template>
</xsl:stylesheet> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...