Список выбора идентификатора, заканчивающегося переменной - PullRequest
1 голос
/ 28 октября 2011

Я хочу выбрать все узлы для данного идентификатора, но это может закончиться дополнительным номером.Как я могу это сделать?

Пример:

 <group id="list">
 <group id="list1">
 <group id="list2">
 <group id="map">
 <group id="map1">

Объявление, которое у меня сейчас:

<xsl:variable name="rule">
<data>
    <node>list</node>
    <node>map</node>
</data>
</xsl:variable>

<xsl:template match="/">
    <xsl:apply-templates select=".//group[ @id = exslt:node-set($rule)/data/node]"/>
</xsl:template>

, и позволяет мне работать только наузлы, указанные в списке «правил».[XSLT v1.0]

Пожалуйста, сообщите.

1 Ответ

1 голос
/ 28 октября 2011

I.Решение XSLT 1.0:

Это преобразование:

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pIds">
  <id>list</id>
  <id>map</id>
 </xsl:param>

 <xsl:variable name="vIds" select=
  "document('')/*/xsl:param[@name='pIds']/*"/>

 <xsl:template match="group">
  <xsl:if test=
  "$vIds[. = current()/@id
        or
         starts-with(current()/@id, .)
        and
         substring-after(current()/@id, .)
        =
         floor(substring-after(current()/@id, .))
        ]
  ">
   <!-- Processing here: -->
   <xsl:copy-of select="."/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

при применении к этому документу XML :

<t>
 <group id="list"/>
 <group id="list1"/>
 <group id="listX"/>
 <group id="list2"/>
 <group id="map"/>
 <group id="map123Z"/>
 <group id="map1"/>
</t>

обрабатывает (в этом примере копирует) точно совпадающие узлы :

<group id="list"/>
<group id="list1"/>
<group id="list2"/>
<group id="map"/>
<group id="map1"/>

Пояснение :

  1. Использование стандартных функций XPathstarts-with(), substring-after() и floor().

  2. Простой тест, если строка преобразуется в целое число: floor($s) = $s

II.Решение XSLT 2.0:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:xs="http://www.w3.org/2001/XMLSchema">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:param name="pIds" select="'list', 'map'"/>

 <xsl:variable name="vIds" select=
  "document('')/*/xsl:param[@name='pIds']/*"/>

 <xsl:template match=
 "group
   [@id = $pIds
   or
    $pIds
      [starts-with(current()/@id, .)
     and
        substring-after(current()/@id, .)
       castable as
        xs:integer
       ]
    ]
 ">
   <!-- Processing here: -->
   <xsl:copy-of select="."/>
 </xsl:template>
</xsl:stylesheet>

Объяснение : Это решение очень похоже на решение XSLT 1.0 со следующими основными отличиями:

  1. В XSLT 2.0 разрешено иметь ссылки на переменные / параметры в шаблоне сопоставления.Используя это, мы избегаем <xsl:if> внутри тела шаблона.

  2. Мы определяем параметр, чтобы он содержал последовательность желаемых строк.

  3. Мы используем стандартный оператор XPath 2.0 castable as.

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