2012-06-22 81 views
2

我想加入兩個xml文件,如下圖所示。然而,我的問題是你如何做到這一點與加入一個ID。我想要做關於POSITION而不是id的連接。你將如何爲以下文件做這件事?XSLT - 合併2 XML文件不具有公共ID

文件1:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<catalog> 
    <data> 
    <title>Title1</title> 
    <description>Description1</description> 
    </data> 

    <data> 
    <title>Title2</title> 
    <description>Description2</description> 
    </data> 
</catalog> 

文件2:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<catalog> 
    <data> 
    <author>Author1</author> 
    <date>12/34/5678</date> 
    </data> 

    <data> 
    <author>Author2</author> 
    <date>87/65/4321</date> 
    </data> 
</catalog> 

輸出:

<?xml version="1.0" encoding="ISO-8859-1"?> 
<catalog> 
    <data> 
    <title>Title1</title> 
    <description>Description1</description> 
    <author>Author1</author> 
    <date>12/34/5678</date> 
    </data> 

    <data> 
    <title>Title2</title> 
    <description>Description2</description> 
    <author>Author2</author> 
    <date>87/65/4321</date> 
    </data> 
</catalog> 

我知道該怎麼做,如果你使用下面的XSLT有一個共同的ID場但是,你如何加入POSITION?

<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes" /> 
    <xsl:variable name="with" select="'File2.xml'" /> 

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

    <xsl:template match="scene"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
     <xsl:variable name="info" select="document($with)/catalog/data[id=current()/id]/." /> 
     <xsl:for-each select="$info/*"> 
     <xsl:if test="name()!='myid'"> 
      <xsl:copy-of select="." /> 
     </xsl:if> 
     </xsl:for-each> 
    </xsl:copy> 
    </xsl:template> 
</xsl:transform> 

回答

1
<?xml version="1.0" encoding="ISO-8859-1"?> 
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes" /> 
    <xsl:variable name="with" select="'File2.xml'" /> 

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

    <xsl:template match="data"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()" /> 
      <!--Determine the index of the current data element in this document. 
        Note: using position() may not always yield the desired number 
         because other siblings (text(), comment(), 
         processing-instruction(), 
         or other elements) would affect position(). 
         Also, counting preceeding-siblings that are data 
         elements, not just any element. --> 
      <xsl:apply-templates 
       select="document($with) 
       /catalog 
       /data[position() 
         = count(current()/preceding-sibling::data)+1] 
       /*[name()!='myid']" /> 
       <!--kept filter for `myid` elements from example stylesheet, 
        remove if not needed --> 
     </xsl:copy> 
    </xsl:template> 
</xsl:transform> 
1

嘗試

<xsl:strip-space elements="*"/> 
<xsl:output indent="yes"/> 

<xsl:param name="url2" select="'input2.xml'"/> 
<xsl:variable name="data2" select="document($url2)/catalog/data"/> 

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

<xsl:template match="data"> 
    <xsl:variable name="pos" select="position()"/> 
    <xsl:copy> 
    <xsl:apply-templates select="@* | * | $data2[$pos]/*"/> 
    </xsl:copy> 
</xsl:template> 
1
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> 
    <xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes" /> 
    <xsl:variable name="with" select="'File2.xml'" /> 

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

    <xsl:template match="data"> 
    <xsl:copy> 
     <xsl:apply-templates select="@*|node()" /> 
     <!-- using count to get the current position of the elements is safer --> 
     <xsl:copy-of select="document($with)/catalog/ 
     data[position()=count(current()/preceding-sibling::*) + 1]/*"/> 
    </xsl:copy> 
    </xsl:template> 
</xsl:transform>