2

我想加入两个 xml 文件,如下图所示。但是我的问题是,如果您有一个 ID 可以加入,您将如何做到这一点。我想加入关于 POSITION 而不是 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>

如果您有一个ID使用下面 XSLT 的公共字段,我知道该怎么做,但是您如何加入 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>
4

3 回答 3

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>
于 2012-06-22T11:22:50.697 回答
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>
于 2012-06-22T11:47:38.790 回答
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>
于 2012-06-22T11:56:32.063 回答