Как получить доступ к одному XPath в XSLT при доступе к другому XPath? - PullRequest
2 голосов
/ 23 ноября 2011

Представленный образец является упрощенной версией того, что я пытаюсь сделать.

Используя XSLT, как мне сравнить данные из узлов в разных (не-child) xpath?Я хочу сравнить каждый cd/artist с dvd/director, чтобы увидеть, совпадают ли они (см. Примеры ниже).Есть несколько CD и DVD, но в этом упрощенном примере я использовал только один из каждого.Я попытался сделать сравнение в пределах одного шаблона, но я не смог получить доступ к dvd xpath.И я не мог получить доступ к dvd xpath с помощью отдельного шаблона.При использовании отдельного шаблона я создал шаблон сравнения, который я назвал (<xsl:call-template name="compare">).Под доступом я имею в виду, что я не смог распечатать значение dvd / Director.

Мой вопрос: как получить доступ к одному xpath при доступе к другому xpath?То, что я хочу сделать, это сравнить CD Artist с DVD-директором, чтобы увидеть, если они совпадают.И распечатайте эти значения, если они совпадают.Я не могу понять, как найти художника и режиссера, чтобы я мог сравнить их.Мой xslt печатает значение исполнителя компакт-диска, но я не могу распечатать значение dvd / Director.

Мои образцы следующие:

Образцы получены из W3Schools.Я изменил их, чтобы проиллюстрировать мой вопрос.

Образец XSLT

<xsl:for-each select="catalog/cd">
   <xsl:value-of select="@artist"/>
    <xsl:for-each select="catalog/dvd">         
    <xsl:if test="@director = @artist">
        <xsl:value-of select="@director"/>
    </xsl:if>           
   </xsl:for-each>
 </xsl:for-each>

Образец XML

<?xml version="1.0" encoding="ISO-8859-1"?>
<catalog>   
<cd title="Unchain my heart" artist="Joe Cocker">

    <country>USA</country>
    <company>EMI</company>
    <price>8.20</price>
    <year>1987</year>
</cd>

    <dvd title="My DVD Movie" director="Joe Cocker">
    <country>USA</country>
    <company>WB</company>
    <price>20.00</price>
    <year>1999</year>
    </dvd>
</catalog>

Заранее спасибо за помощь.

Ответы [ 4 ]

1 голос
/ 23 ноября 2011

Я думаю, что большая проблема в том, что вы думаете с процедурной точки зрения, что редко является правильным способом решения проблемы с XSLT.Лучше всего сначала сопоставить элементы cd, а затем выбрать элементы dvd, для которых director соответствует artist.Рассмотрим следующую таблицу стилей:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="/*/cd">
        <xsl:value-of select="artist"/>
        <xsl:apply-templates select="../dvd[director=current()/artist]"
            mode="out"/>
    </xsl:template>
    <xsl:template match="dvd" mode="out">
        <xsl:value-of select="director"/>
    </xsl:template>
    <xsl:template match="dvd"/>
</xsl:stylesheet>

Первый шаблон применяет шаблоны ко всем dvd элементам, для которых следующий предикат оценивается как true: director=current()/artist

Конечно, как в вашем примере,мы просто печатаем имя Joe Cocker дважды, что не очень полезно.

Примечание: Этот подход ломается, когда существует более одного cd элемента с одинаковым artist.Более сложные стратегии группировки могут решить эту проблему.

0 голосов
/ 23 ноября 2011

Вы можете упростить for-each и использовать current() ...

<xsl:for-each select="catalog/cd">
  <xsl:value-of select="artist"/>
  <xsl:for-each select="../dvd[director = current()/artist]">
      <xsl:value-of select="director"/>                   
  </xsl:for-each>
</xsl:for-each>
0 голосов
/ 23 ноября 2011

Ну и несколько указателей:

<xsl:for-each select="catalog/cd">

Когда вы делаете это, вы «внутри» каждого элемента каталога / CD. Поэтому ваш current () представляет собой элемент eacy catalog / cd.

Ваша "функция сравнения":

<xsl:if test="@director = @artist">

Не работает, так как вы пытаетесь сравнить атрибуты директора и исполнителя. Но нет атрибутов режиссера и художника, и даже если бы они были, вы бы попытались сравнить атрибуты catalog/dvd.

Таким образом, элемент dvd должен был бы быть таким, как <dvd director="foo" artist="bar"/> и т.д ..

Я полагаю, что вы действительно пытаетесь найти компакт-диски и DVD, которые имеют одного и того же исполнителя / режиссера. Мне не ясно, чего вы пытаетесь достичь. Если вы уточните, вы получите лучший ответ.

0 голосов
/ 23 ноября 2011

Сделать так:

 <xsl:for-each select="/catalog/dvd">   

Без косой черты "/" каталог / dvd относительно текущего узла, который устанавливается <xsl:for-each select="catalog/cd">

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