XSL: поиск узла на основе содержимого другого узла - PullRequest
2 голосов
/ 11 марта 2012

У меня есть XML-файл, который выглядит так:

<container>
<bugs>
    <bug id="b1">
        <reporter>Tom</reporter>
        ...
    </bug>
    <bug id="b2">
        <reporter>Jane</reporter>
        ...
    </bug>
</bugs>
<users>
    <user>
        <userid>10</userid>
        <username>Tom</username>
    </user>
    <user>
        <userid>5</userid>
        <username>Jane</username>
    </user>
</users>
</container>

Конечный результат должен быть:

<items>
    <item>
        <bugid>b1</bugid>
        <author id="10">Tom</author>
    </item>
    <item>
        <bugid>b2</bugid>
        <author id="5">Jane</author>
    </item>
</items>

Проблема: я не могу получить правильное сравнение для поиска идентификатора.

Я предположил, что это будет так:

<xsl:template match="bug">
....
    <xsl:element name="author">
        <xsl:attribute name="id">
            <xsl:value-of select="//users/user[username=reporter]/userid"/>
        </xsl:attribute>
    </xsl:element>
....
</xsl:template>

Но это возвращает пустой идентификатор (id = "").

<xsl:value-of select="//users/user[username='Tom']/userid"/>

возвращает 10 и

<xsl:value-of select="reporter"/>

возвращает Тома.

Я не вижу, что здесь не так.

Ответы [ 2 ]

2 голосов
/ 11 марта 2012
//users/user[username=reporter]/userid

ищет user, содержащий равные username и reporter элементы. Он не ищет reporter в вашем bug.

Вы можете заставить это работать, сначала привязав имя репортера к переменной:

<xsl:element name="author">
  <xsl:variable name="reporter" select="string(reporter)"/>
  <xsl:attribute name="id">
    <xsl:value-of select="//users/user[username=$reporter]/userid"/>
  </xsl:attribute>
</xsl:element>
0 голосов
/ 11 марта 2012

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

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

 <xsl:key name="kUIdByName" match="userid" use="../username"/>

 <xsl:template match="bugs">
  <items>
   <xsl:apply-templates/>
  </items>
 </xsl:template>

 <xsl:template match="bug">
  <item>
   <bugid><xsl:value-of select="@id"/></bugid>
   <xsl:apply-templates/>
  </item>
 </xsl:template>

 <xsl:template match="reporter">
  <author id="{key('kUIdByName',.)}"><xsl:value-of select="."/></author>
 </xsl:template>
 <xsl:template match="text()"/>
</xsl:stylesheet>

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

<container>
    <bugs>
        <bug id="b1">
            <reporter>Tom</reporter>     
        </bug>
        <bug id="b2">
            <reporter>Jane</reporter>     
        </bug>
    </bugs>
    <users>
        <user>
            <userid>10</userid>
            <username>Tom</username>
        </user>
        <user>
            <userid>5</userid>
            <username>Jane</username>
        </user>
    </users>
</container>

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

<items>
   <item>
      <bugid>b1</bugid>
      <author id="10">Tom</author>
   </item>
   <item>
      <bugid>b2</bugid>
      <author id="5">Jane</author>
   </item>
</items>

Пояснение : правильное использование клавиш для поиска.

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