如何使用XSLT连接两个XML文件?

时间:2014-05-19 03:04:14

标签: xml xslt xpath

我正在尝试加入两个xml文件,其中包含可以链接的彼此的详细信息,但我不确定如何。

" movies.xml"

<movies>
    <movie>
      <title></title>
      <studio><studio>
      <date></date>
    </movie>
</movies>

&#34; studios.xml&#34;

<studios>
    <studio>
      <name></name>
      <founded></founded>
      <location></location>
    </studio>
</studios>

输出

<studios>
  <studio>
    <name></name>
    <founded></founded>
    <location></location>
    <movie>
        <name></name>
    </movie>
    <movie>
        <name></name>
    </movie>
  </studio>
</studios>

我已经简化了文件,但仍然有效。 我的想法是使用工作室作为基础只是获得价值并插入,但是当谈到将电影加入到正确的工作室时我很困惑。

我目前尝试遍历每部电影,直到找到相同的匹配名称,在电影中工作室,在电影院中名称

但目前的尝试不起作用,这种可能吗?

编辑: 有一个工作室,但它可以有很多电影,在工作室有几个工作室 在电影中有几部电影。 如果一个工作室有多个电影而不是它可以作为名称添加,那么每个工作室都可能有几个电影元素。

我要做的是,获取所有电影并将它们添加到正确的工作室。

虚拟数据: Movies.xml

<movies>
<movie>
  <title>Lord of XSLT</title>
  <studio>Great XML<studio>
  <date>1-1-2014</date>
</movie>
<movie>
  <title>On the XML</title>
  <studio>XML2.0<studio>
  <date>5-1-2004</date>
</movie>
<movie>
  <title>On the XPath</title>
  <studio>Great XML<studio>
  <date>5-5-2013</date>
</movie>
</movies>

Studios.xml

<studios>
<studio>
  <name>Great XML</name>
  <founded>1-1-1999</founded>
  <location>USA</location>
</studio>
<studio>
  <name>XML2.0</name>
  <founded>9-9-1998</founded>
  <location>ENGLAND</location>
</studio>
</studios>

的Output.xml

<studios>
<studio>
   <name>Great XML</name>
   <founded>1-1-1999</founded>
   <location>ENGLAND</location>
   <movie>
    <name>Lord of XSLT</name>
   </movie>
   <movie>
    <name>On the XPath</name>
   </movie>
 </studio>
  <studio>
   <name>XML2.0</name>
   <founded>9-9-1998</founded>
   <location>ENGLAND</location>
    <movie>
     <name>On the XML</name>
    </movie>
  </studio>
</studios>

尝试

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

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

<xsl:template match="/studios">

<xsl:for-each select="studio">
<studio>
    <name><xsl:value-of select="name"/></name>
    <founded><xsl:value-of select="founded"/></founded>
    <location><xsl:value-of select="location"/></location>

    <xsl:for-each select="document('movies.xml')/movies/movie">
        <movies>

        </movies>
    </xsl:for-each>

</studio>

</xsl:for-each>     

</xsl:template>

</xsl:stylesheet>

2 个答案:

答案 0 :(得分:3)

你有正确的想法。我建议您使用xsl:apply-templates代替xsl:for-each并让identity transform处理大部分工作。 (推而不是拉。)

示例...

<强> Studios.xml

<studios>
    <studio>
        <name>Great XML</name>
        <founded>1-1-1999</founded>
        <location>USA</location>
    </studio>
    <studio>
        <name>XML2.0</name>
        <founded>9-9-1998</founded>
        <location>ENGLAND</location>
    </studio>
</studios>

Movies.xml (已修复为格式良好)

<movies>
    <movie>
        <title>Lord of XSLT</title>
        <studio>Great XML</studio>
        <date>1-1-2014</date>
    </movie>
    <movie>
        <title>On the XML</title>
        <studio>XML2.0</studio>
        <date>5-1-2004</date>
    </movie>
    <movie>
        <title>On the XPath</title>
        <studio>Great XML</studio>
        <date>5-5-2013</date>
    </movie>
</movies>

XSLT 1.0

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

    <xsl:variable name="movies" select="document('Movies.xml')"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="studio">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()|$movies/*/movie[studio=current()/name]/title"/>
        </xsl:copy>        
    </xsl:template>

    <xsl:template match="movie/title">
        <movie>
            <name><xsl:value-of select="."/></name>
        </movie>
    </xsl:template>

</xsl:stylesheet>

<强>输出

<studios>
   <studio>
      <name>Great XML</name>
      <founded>1-1-1999</founded>
      <location>USA</location>
      <movie>
         <name>Lord of XSLT</name>
      </movie>
      <movie>
         <name>On the XPath</name>
      </movie>
   </studio>
   <studio>
      <name>XML2.0</name>
      <founded>9-9-1998</founded>
      <location>ENGLAND</location>
      <movie>
         <name>On the XML</name>
      </movie>
   </studio>
</studios>

答案 1 :(得分:2)

这是一个相对简单的方法来看待它:

<?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" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/studios">
    <studios>
        <xsl:for-each select="studio">
            <studio>
                <xsl:copy-of select="*"/>
                <movies>
                    <xsl:for-each select="document('movies.xml')/movies/movie[studio=current()/name]">
                        <xsl:copy-of select="."/>
                    </xsl:for-each>
                </movies>
            </studio>
        </xsl:for-each>     
    </studios>
</xsl:template>

</xsl:stylesheet>

当然,您必须先修复movies.xml文档(正确关闭标记)。