1

xslt を使用して 2 つの xml ファイルを 1 つの xml ファイルにマージする方法を知りたいです。予想される出力に示すように、これらの両方のxmlファイルをxmlファイルにマージしたい.2番目のファイルから、ファイル1の同じ番号の対応するブロックに各ノードHnを含めたい.

ファイル1:

<Test>
  <R1>
    <Th1>
        here are some instruction.
    </Th1>
  </R1>

  <R2>
    <Th2>
        here are some instruction.
    </Th2>
  </R2>

  <R3>
    <Th3>
        here are some instruction.
    </Th3>
  </R3>
</Test>

ファイル 2:

<test1>
  <H1>
    here are some instruction.
  </H1>

  <H2>
    here are some instruction.
  </H2>

  <H3>
    here are some instruction.
  </H3>
</test1>    

期待される出力は次のとおりです。

<test2>
  <R1>
    <H1>
        here are some instruction.
    </H1>
    <Th1>
        here are some instruction.
    </Th1>
  </R1>

  <R2>
    <H2>
        here are some instruction.
    </H2>
    <Th2>
        here are some instruction.
    </Th2>
  </R2>

  <R3>
    <H3>
        here are some instruction.
    </H3>
    <Th3>
        here are some instruction.
    </Th3>
  </R3>

</test2>

ご協力いただきありがとうございます。

4

1 に答える 1

2

I.このXSLT1.0変換

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>

 <xsl:variable name="vDigits" select="'0123456789'"/>
 <xsl:variable name="vDoc2" select="document('file:///c:/temp/delete/file2.xml')"/> 

 <xsl:template match="/*">
     <test2><xsl:apply-templates/></test2>
 </xsl:template>

 <xsl:template match="/*/*">
  <xsl:copy>
   <xsl:text>&#xA;</xsl:text>
   <xsl:copy-of select=
    "$vDoc2/*/*
      [translate(name(),translate(name(),$vDigits,''),'')
      =
       translate(name(current()),translate(name(current()),$vDigits,''),'')
      ]"/>
    <xsl:copy-of select="node()"/>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

最初のXMLドキュメント(file1.xml)に適用した場合:

<Test>
  <R1>
    <Th1>
        here are some instruction.
    </Th1>
  </R1>

  <R2>
    <Th2>
        here are some instruction.
    </Th2>
  </R2>

  <R3>
    <Th3>
        here are some instruction.
    </Th3>
  </R3>
</Test>

2番目のXMLドキュメントを次の場所に配置しますc:\temp\delete\file2.xml

<test1>
  <H1>
    here are some instruction.
  </H1>

  <H2>
    here are some instruction.
  </H2>

  <H3>
    here are some instruction.
  </H3>
</test1>

必要な正しい結果を生成します。

<test2>
  <R1>
<H1>
    here are some instruction.
  </H1>
    <Th1>
        here are some instruction.
    </Th1>
  </R1>

  <R2>
<H2>
    here are some instruction.
  </H2>
    <Th2>
        here are some instruction.
    </Th2>
  </R2>

  <R3>
<H3>
    here are some instruction.
  </H3>
    <Th3>
        here are some instruction.
    </Th3>
  </R3>
</test2>

説明

MichaelKayによって最初にデモされた「 double-translate」メソッドの適切な使用。


II。XSLT 2.0ソリューション

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes"/>

 <xsl:variable name="vDigits" select="'0123456789'"/>
 <xsl:variable name="vDoc2" select="document('file:///c:/temp/delete/file2.xml')"/> 

 <xsl:template match="/*">
     <test2><xsl:apply-templates/></test2>
 </xsl:template>

 <xsl:template match="/*/*">
  <xsl:if test="not(matches(name(), '^.+\d+$'))">
    <xsl:message terminate="yes">
     Element Name doesn't end with number: <xsl:sequence select="name()"/>
    </xsl:message>
  </xsl:if>
  <xsl:copy>
   <xsl:text>&#xA;</xsl:text>
   <xsl:copy-of select=
    "$vDoc2/*/*
      [replace(name(),'^.+(\d+)$', '$1')
      =
       replace(name(current()),'^.+(\d+)$', '$1')
      ]"/>
    <xsl:copy-of select="node()"/>
   </xsl:copy>
 </xsl:template>
</xsl:stylesheet>

説明

標準のXPath2.0関数の適切な使用matches()replace()

于 2012-09-14T12:13:16.990 に答える