Базовый XML / XSLT - значение, когда существует несколько элементов с одинаковым именем - PullRequest
3 голосов
/ 04 декабря 2011

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

например. -

<catalog>
<cd>
    <title>Empire Burlesque</title>
    <artist>Bob Dylan</artist>
            <artist>Bob Dylan2</artist>
            <artist>Bob Dylan3</artist>
    <country>USA</country>
    <company>Columbia</company>
    <price>10.90</price>
    <year>1985</year>
</cd>
</catalog>

Теперь, когда я проверяю каждый диск на каждом компакт-диске и использую значение-для вывода имени исполнителя, я получаю только первый элемент (несколько понятно). Но как мне получить ВСЕ элементы с одинаковым именем в цикле for-each? Я пытался выполнить внутренний цикл for-each, но ничего не получилось.

Я очень плохо знаком с XML и с тем, как он работает, поэтому, пожалуйста, будьте осторожны со мной ...: - (

Ответы [ 6 ]

7 голосов
/ 04 декабря 2011
<xsl:template match="/">
    <xsl:for-each select="catalog">
        <!-- Print Other Stuff, if required -->
        <xsl:for-each select="cd/artist">
            <xsl:value-of select="text()"/><br/>
        </xsl:for-each>
    </xsl:for-each>
</xsl:template>

Выход:

Боб Дилан
Боб Дилан2
Боб Дилан3

3 голосов
/ 05 декабря 2011

Теперь, когда я for-each через каждый CD и использую value-of, чтобы вывести Имя художника, я получаю только первый элемент (несколько понятно). Но как мне получить ВСЕ элементы с одинаковым именем в for-each цикл? Я попытался сделать внутренний цикл for-each, но не сработал.

Мой совет любому новичку в XSLT: , а не до , используйте <xsl:for-each> - как можно больше . Мне известен только один вариант использования, где необходим <xsl:for-each>, и это очень редко встречающийся случай (когда необходимо явно изменить текущий документ, чтобы функция key() использовала индекс, созданный для этого конкретного документ).

Это, вероятно, одно из самых простых возможных решений (без <xsl:for-each> и без вложенности):

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output method="text"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="artist">
  <xsl:value-of select="concat(., '&#xA;')"/>
 </xsl:template>

 <xsl:template match="text()"/>
</xsl:stylesheet>

когда это преобразование применяется к предоставленному документу XML :

<catalog>
    <cd>
        <title>Empire Burlesque</title>
        <artist>Bob Dylan</artist>
        <artist>Bob Dylan2</artist>
        <artist>Bob Dylan3</artist>
        <country>USA</country>
        <company>Columbia</company>
        <price>10.90</price>
        <year>1985</year>
    </cd>
</catalog>

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

Bob Dylan
Bob Dylan2
Bob Dylan3
2 голосов
/ 04 декабря 2011
<xsl:template match="catalog/cd/artist">
    <xsl:value-of select="." />
</xsl:template>
0 голосов
/ 05 декабря 2011

Синтаксис text() xpath выбирает любые текстовые дочерние узлы текущего указанного узла.

некоторым не нравится этот сайт, но для начала неплохо указать вам правильное направление - нажмите здесь

0 голосов
/ 04 декабря 2011

Ваш XPATH вероятно неверен:

Находясь в элементе CD с использованием foreach:

  <xsl:template match="/">
    <xsl:for-each select="//cd">
      <xsl:for-each select="artist">
        <xsl:message terminate="no">
          <xsl:value-of select="."/>
        </xsl:message>
      </xsl:for-each>
    </xsl:for-each>
  </xsl:template>

Это печатает всех художников ..

0 голосов
/ 04 декабря 2011

Нет причин, чтобы внутренний цикл не работал. Какой синтаксис XSLT вы использовали для этого? Похоже, что в ваших xpaths или что-то есть ошибка, потому что то, что вы описали, должно работать нормально.

...