XSLT: использование переменных в ключевой функции (продолжение) - PullRequest
1 голос
/ 01 февраля 2012

У меня есть следующий XML-файл:

<titles> 
   <book title="XML Today" author="David Perry"/> 
   <book title="XML and Microsoft" author="David Perry"/> 
   <book title="XML Productivity" author="Jim Kim"/> 
   <book title="XSLT 1.0" author="Albert Jones"/> 
   <book title="XSLT 2.0" author="Albert Jones"/> 
   <book title="XSLT Manual" author="Jane Doe"/> 
</titles> 

и преобразование для удаления элементов с @author, начинающееся с 'David' или 'Jane':

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">

  <xsl:output method="xml" indent="yes"/>

  <xsl:strip-space elements="*"/>

  <xsl:key name="author1-search" match="book[starts-with(@author, 'David')]" use="@title"/>
  <xsl:template match="book [key('author1-search', @title)]" />

  <xsl:key name="author2-search" match="book[starts-with(@author, 'Jane')]" use="@title"/>
  <xsl:template match="book [key('author2-search', @title)]" />

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

Ожидаемыйрезультатом будет следующий XML-файл:

<titles> 
   <book title="XML Productivity" author="Jim Kim"/> 
   <book title="XSLT 1.0" author="Albert Jones"/> 
   <book title="XSLT 2.0" author="Albert Jones"/> 
</titles>

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

  <xsl:param name="pAuthors"> 
      <x>David Perry</x> 
      <x>Jane Doe</x> 
     </xsl:param> 

Можно ли применить этот метод, чтобы переписать приведенное выше преобразование, чтобы он использовал параметр pAuthors исодержать только один общий ключ поиска (вместо author1-search, author2-search и т. д.)?XSLT 2.0 и функция document () не поддерживаются.

Заранее спасибо, Leo

1 Ответ

1 голос
/ 02 февраля 2012

Из догадок, рассматривающих код, я полагаю, что OP - это то, как использовать ключи XSLT, чтобы помочь исключить книги, написанные любым автором из данного набора авторов.

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

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

    <xsl:param name="pAuthors">
        <x>David Perry</x>
        <x>Jane Doe</x>
    </xsl:param>

    <xsl:variable name="vParams" select=       "
      ext:node-set($pAuthors)/*"/>

  <xsl:key name="kBookByAuthor" match="book"
           use="@author"/>  

  <xsl:variable name="vBooksToExclude" select=
   "key('kBookByAuthor', $vParams)"/>

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

 <xsl:template match="book">
  <xsl:if test="count(.|$vBooksToExclude) != count($vBooksToExclude)">
    <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

при применении к предоставленному документу XML :

<titles>
    <book title="XML Today" author="David Perry"/>
    <book title="XML and Microsoft" author="David Perry"/>
    <book title="XML Productivity" author="Jim Kim"/>
    <book title="XSLT 1.0" author="Albert Jones"/>
    <book title="XSLT 2.0" author="Albert Jones"/>
    <book title="XSLT Manual" author="Jane Doe"/>
</titles>

дает требуемый, правильный результат, в котором любая книга, имеющаяавтор из предоставленного набора авторов (Дэвид Перри и Джейн Доу) пропускается :

<titles>
   <book title="XML Productivity" author="Jim Kim"/>
   <book title="XSLT 1.0" author="Albert Jones"/>
   <book title="XSLT 2.0" author="Albert Jones"/>
</titles>

Пояснение :

Мы используем следующее выражение XPathчтобы определить, не принадлежит ли узел $n к набору узлов $s:

count($n | $s) != count($s)

Окончательное обновление :

Как хочет OP,здесь мы исключаем из копирования на выход все книги, у которых есть автор, чье имя указывается в качестве одного из многих значений во внешнем / глобальном параметре. Мы по-прежнему используем один ключ.

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:ext="http://exslt.org/common">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

    <xsl:param name="pAuthors">
        <x>David</x>
        <x>Jane</x>
    </xsl:param>

    <xsl:variable name="vParams" select=       "
      ext:node-set($pAuthors)/*"/>

  <xsl:key name="kBookByAuthor" match="book"
           use="substring-before(@author, ' ')"/>

  <xsl:variable name="vBooksToExclude" select=
   "key('kBookByAuthor', $vParams)"/>

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

 <xsl:template match="book">
  <xsl:if test="count(.|$vBooksToExclude) != count($vBooksToExclude)">
    <xsl:call-template name="identity"/>
  </xsl:if>
 </xsl:template>
</xsl:stylesheet>

, когда это преобразование применяется к следующему документу XML (добавлен еще один автор David):

<titles>
    <book title="XML Today" author="David Perry"/>
    <book title="XML and Microsoft" author="David Perry"/>
    <book title="Just example" author="David Masters"/>
    <book title="XML Productivity" author="Jim Kim"/>
    <book title="XSLT 1.0" author="Albert Jones"/>
    <book title="XSLT 2.0" author="Albert Jones"/>
    <book title="XSLT Manual" author="Jane Doe"/>
</titles>

дает желаемый, правильный результат :

<titles>
  <book title="XML Productivity" author="Jim Kim" />
  <book title="XSLT 1.0" author="Albert Jones" />
  <book title="XSLT 2.0" author="Albert Jones" />
</titles>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...