Преобразуйте список элементов в последовательность, разделенную запятыми - PullRequest
1 голос
/ 11 ноября 2010

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

Я нашел несколько примеров в руководствах, чтобы сделать это для text output, но ничего для вывода XML.

Пример ввода:

<People>
    <Person>John</Person>
    <Person>Paul</Person>
    <Person>George</Person>
    <Person>Ringo</Person>
</People>

Желаемый вывод:

<Output>
    <People>John,Paul,George,Ringo</People>
</Output>

Вот что я получил до сих пор:

<?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:template match="/">
         <xsl:element name="Output">
                <xsl:element name="People">
                       <xsl:for-each select="People/Person">
                              <xsl:value-of select="."/>
                              <xsl:text>,</xsl:text>
                       </xsl:for-each>
                </xsl:element>
         </xsl:element>
    </xsl:template>

</xsl:stylesheet>

Но я не знаю, как избавиться от последней комы, используя этот подход. Есть идеи?

Ответы [ 2 ]

3 голосов
/ 11 ноября 2010

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

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

 <xsl:template match="/*">
  <People>
    <xsl:apply-templates/>
  </People>
 </xsl:template>

 <xsl:template match="Person">
  <xsl:value-of select=
    "concat(.,
            substring(',', 1 div not(position()=last()))
            )"/>
 </xsl:template>
</xsl:stylesheet>

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

<People>
    <Person>John</Person>
    <Person>Paul</Person>
    <Person>George</Person>
    <Person>Ringo</Person>
</People>

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

<People>John,Paul,George,Ringo</People>

Обратите внимание :

  1. Не допускаются структурные зависимости между элементами впоследовательность - например, мы не используем тот факт, что они являются братьями и сестрами.

  2. Приведенный выше факт делает наше преобразование более универсальным - его можно использовать вситуации, когда элементы последовательности не являются братьями и сестрами или даже принадлежат более чем одному документу XML.

  3. Умный трюк XPath 1.0 помогает избежать использования различных шаблонов дляпервый / последний элемент, а в остальном:

В XPath 1.0 true(), false() преобразуются в 1, 0.

1 div 0 - positive-infinity и substring(anyString, 1, $x), где $x - positive-infinity, полная строка.

2 голосов
/ 11 ноября 2010

Это должно работать:

<?xml version="1.0" encoding="ISO-8859-1"?>

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<xsl:template match="/">
<Output>
 <People>
   <xsl:apply-templates select="People/Person" />
 </People>
</Output>
</xsl:template>

<xsl:template match="Person">
  <xsl:value-of select="normalize-space(.)" /><xsl:if test="following-sibling::Person">,</xsl:if>
</xsl:template>

</xsl:stylesheet>

Примечание: это не будет производить CSV с кавычками вокруг каждого значения.

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