2012-04-23 3 views
1

У меня есть этот XML:XSLT-преобразование элементов, которые Значение ключа

<Year> 
    <Movies> 
    <Add> 
     <Key>movie1</Key> 
     <Value>black</Value> 
    </Add> 
    <Add> 
     <Key>movie2</Key> 
     <Value>white</Value> 
    </Add> 
    </Movies> 
</Year> 

Это должно быть преобразован в этот XML, с помощью специального Астерикс как отправного характер, а также:

<Year> 
    <MovieList>*movie1-black,movie2-white<MovieList> 
</Year> 

Я пробовал несколько вариантов преобразований xslt, и я повсюду. Это мой последний взлом. Возился с этим в инструменте XML прямо сейчас ...

<xsl:template match="b:Year"> 
<xsl:copy> 
    <xsl:for-each select="*"> 
     <xsl:element name="MovieList"> 
     <xsl:for-each select="./b:Movies/b:Add"> 
      <xsl:if test="position() = 1">*</xsl:if> 
      <xsl:value-of select="./b:Key"/>-<xsl:value-of select="./b:Value"/> 
      <xsl:if test="position() != last()">,</xsl:if> 
     </xsl:for-each> 
     </xsl:element> 
    </xsl:for-each> 
    <xsl:apply-templates select="node()"/> 
</xsl:copy> 
</xsl:template> 

Все специалисты с некоторыми XSLT руководства по этому вопросу? Благодаря!

ответ

0

I. Это простое и эффективное т XSLT 1.0 преобразование (нет переменных и не пост-обработка результатов):

<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="/*"> 
    <Year> 
    <xsl:apply-templates/> 
    </Year> 
</xsl:template> 

<xsl:template match="Movies"> 
    <MovieList> 
    <xsl:apply-templates/> 
    </MovieList> 
</xsl:template> 

<xsl:template match="Add"> 
    <xsl:value-of select="substring('*,', 2 - (position()=1),1)"/> 
    <xsl:value-of select="concat(Key, '-', Value)"/> 
</xsl:template> 
</xsl:stylesheet> 

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

<Year> 
    <Movies> 
     <Add> 
      <Key>movie1</Key> 
      <Value>black</Value> 
     </Add> 
     <Add> 
      <Key>movie2</Key> 
      <Value>white</Value> 
     </Add> 
    </Movies> 
</Year> 

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

<Year> 
    <MovieList>*movie1-black,movie2-white</MovieList> 
</Year> 

II. XSLT 2.0 Решение:

<xsl:stylesheet version="2.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="/*"> 
    <Year> 
    <xsl:apply-templates/> 
    </Year> 
</xsl:template> 

<xsl:template match="Movies"> 
    <MovieList> 
    <xsl:sequence select="'*'[current()/Add]"/> 
    <xsl:value-of select="Add/concat(Key, '-', Value)" 
     separator=","/> 
    </MovieList> 
</xsl:template> 
</xsl:stylesheet> 
+0

Спасибо, Dimitre. Преобразование 1.0 было приятным и чистым. Гораздо лучше, чем направление, в котором я возглавлял. –

+0

@MikeLemke: Добро пожаловать. Использование многих простых шаблонов с соответствующими шаблонами соответствия является одним из наиболее отличительных шаблонов проектирования XSLT, и это приводит к простому, расширяемому и надежному коду. –

+0

Использование неявного преобразования типов из булева в число очень умно. Мне понравилось это;) –

0

Вот что вы можете сделать с помощью XSLT 1.0:

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

    <xsl:template match="Year/Movies"> 
     <Year> 
      <xsl:variable name="movielist"> 
      <xsl:for-each select="Add"> 
       <xsl:value-of select="concat(Key, '-', Value, ',')"/> 
      </xsl:for-each> 
      </xsl:variable> 
      <MovieList> 
       <xsl:value-of select="concat('*',substring($movielist, 0, string-length($movielist)))"/> 
      </MovieList> 
     </Year> 
    </xsl:template> 
</xsl:stylesheet> 

Учитывая ваш вклад он производит:

<Year> 
    <MovieList>*movie1-black,movie2-white</MovieList> 
</Year> 

Вы можете сделать более умный с XSLT 2.0 эксплуатируя атрибут xsl:value-ofseparator, как это было объясняется в аналогичном примере: concatenation two fields in xsl by Dimitre

Смежные вопросы