将XML文档与XSLT结合使用进行分组

时间:2014-05-13 07:47:55

标签: xml xslt

我正在尝试合并两个XML文档,一个是电影列表,另一个是导演列表。他们看起来像这样。 主管

<directors>
  <director>
    <name>director 1</name>
    <born> 5/12/1992 </born>
    <nationality>Italian</nationality>
    <biography>some info on director</biography>
  </director>
  <director>
    <name>director 2 </name>
    <born>21/2/1980</born>
    <nationality>french</nationality>
    <biography>a bit about me</biography>
  </director>

<movies>
  <movie>
    <title> movie1</title>
    <director> director 1 </director>
    <date> 1/2/2010 </date>
    <genre> Action</genre>
  </movie>
  <movie>
    <title> movie2</title>
    <director> director 1 </director>
    <date> 1/2/2010 </date>
    <genre> romance</genre>
  </movie>
  <movie>
    <title> movie3</title>
    <director> director 2 </director>
    <date> 1/2/2010 </date>
    <genre> Action</genre>
  </movie>

我想要输出

<director>
<name>director 1</name>
<born> 5/12/1992 </born>
<nationality>Italian</nationality>
<biography>some info on director</biography>
<movies genre="action">
  <movie>
    <title> movie1</title>
    <date> 1/2/2010 </date>
 </movie>
 <movie>
    <title> movie2</title>
    <date> 1/2/2010 </date>
 </movie>
 <movies genre="romance">
  <movie>
    <title> movie1</title>
    <date> 1/2/2010 </date>
 </movie>
 <movie>
    <title> movie2</title>
    <date> 1/2/2010 </date>
 </movie>

添加每个导演制作的电影,按流派分组。

1 个答案:

答案 0 :(得分:1)

这很简单,我们假设你有一个XML directors.xml

<directors>
<director>
    <name>director 1</name>
    <born> 5/12/1992 </born>
    <nationality>Italian</nationality>
    <biography>some info on director</biography>
</director>
<director>
    <name>director 2</name>
    <born>21/2/1980</born>
    <nationality>french</nationality>
    <biography>a bit about me</biography>
</director>
</directors>

和XML movies.xml

<movies>
<movie>
    <title>movie1</title>
    <director> director 1 </director>
    <date> 1/2/2010 </date>
    <genre> Action</genre>
</movie>
<movie>
    <title>movie2</title>
    <director>director 1</director>
    <date> 1/2/2010 </date>
    <genre> romance</genre>
</movie>
<movie>
    <title> movie3</title>
    <director> director 2</director>
    <date> 1/2/2010 </date>
    <genre> Action</genre>
</movie>
</movies>

如果使用以下XSL样式表转换 directors.xml ,假设 movies.xml 与样式表位于同一目录中,则会得到所需的输出:

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

<xsl:output indent="yes"/>

<xsl:key name="movies-by-genre" match="movie" use="genre"/>

<xsl:template match="directors">
    <directors>
        <xsl:apply-templates select="director"/>
    </directors>
</xsl:template>

<xsl:template match="director">
    <xsl:variable name="name" select="normalize-space(name)"/>
    <xsl:copy>
        <xsl:copy-of select="*"/>
        <xsl:for-each
            select="document('movies.xml')//movie
            [count(. | key('movies-by-genre',genre)[1]) = 1]">
            <xsl:if test="key('movies-by-genre',genre)[normalize-space(director)=$name]">
                <movies genre="{genre}">
                    <xsl:for-each select="key('movies-by-genre',genre)">
                        <xsl:if test="normalize-space(director)=$name">
                            <xsl:apply-templates select="."/>
                        </xsl:if>
                    </xsl:for-each>
                </movies>
            </xsl:if>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

<xsl:template match="movie">
    <movie>
        <xsl:copy-of select="title | date"/>
    </movie>
</xsl:template>

</xsl:stylesheet>

如果您需要更灵活,您还可以将movies.xml的文件名/路径移动到参数中并从转换参数中控制它。