2012-04-23 54 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> 

二, 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

谢谢,迪米特雷。 1.0的转变非常干净。比我领导的方向好得多。 – 2012-04-24 06:31:15

+0

@MikeLemke:不客气。使用许多具有适当匹配模式的简单模板是最具特色的XSLT设计模式之一,并且它产生了简单,可扩展和可靠的代码。 – 2012-04-24 12:09:05

+0

利用从布尔型到数字的隐式类型转换非常聪明。我喜欢这个;) – 2012-04-24 13:09:18

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属性为是在类似的例子中进行了解释:Dimitre的concatenation two fields in xsl