2016-04-14 10 views
0

XSLT Version 1.0から2つのXMLファイルをマージする必要があります。ここでの問題は、第2のXMLファイルの属性を最初のファイルの属性に追加する必要があることです。私の問題を明確にするための例を挙げましょう。XSLTの別のドキュメントから値を取得するには

XML1:

<sample> 
    <tag a="1" b="2" c="3" d="4" /> 
    <tag a="2" b="3" c="4" d="5" /> 
</sample> 

XML2:

<sample> 
    <tag e="5" f="6" g="7" /> 
    <tag e="10" f="12" g="11" /> 
</sample> 

出力:

<sample> 
<tag a="1" b="2" c="3" d="4" e="5" f="6" g="7" /> 
<tag a="2" b="3" c="4" d="5" e="10" f="12" g="11" /> 
</sample> 

私は、このために、次のXSLTを試してみました:

<?xml version="1.0" encoding="UTF-8"?> 
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:ws="http://www.w3schools.com"> 
<xsl:template match="/">     
<xsl:for-each select="sample/tag"> 
<tag> 
    <xsl:attribute name="a"><xsl:value-of select="@a"/></xsl:attribute> 
    <xsl:attribute name="b"><xsl:value-of select="@b"/></xsl:attribute> 
    <xsl:attribute name="c"><xsl:value-of select="@c"/></xsl:attribute> 
    <xsl:attribute name="d"><xsl:value-of select="@d"/></xsl:attribute> 
    <xsl:attribute name="e"><xsl:value-of select="document('xml2.xml')//@e"/></xsl:attribute> 
    <xsl:attribute name="f"><xsl:value-of select="document('xml2.xml')//@f"/></xsl:attribute> 
    <xsl:attribute name="g"><xsl:value-of select="document('xml2.xml')//@g"/></xsl:attribute> 
<tag> 
</xsl:for-each> 

</xbrl> 
</xsl:template> 
</xsl:stylesheet> 

しかし、私は2番目のXMLファイルの最初の行だけを取得しました。 EG私の出力は:

<sample> 
<tag a="1" b="2" c="3" d="4" e="5" f="6" g="7" /> 
<tag a="2" b="3" c="4" d="5" e="5" f="6" g="7" /> 
</sample> 

誰もが私を助けてくれることを願っています。私は完全にXSLTの新機能です。

答えて

1

をお試しください1対1位置マッピング:

<xsl:template match="/sample"> 
    <sample> 
    <xsl:apply-templates select="tag" /> 
    </sample> 
</xsl:template> 

<xsl:template match="tag"> 
    <xsl:variable name="pos" select="position()" /> 
    <tag> 
    <xsl:copy-of select="@*" /> 
    <xsl:copy-of select="document('a2.xml')/sample/tag[$pos]/@*" /> 
    </tag> 
</xsl:template> 

出力は次のとおりです。あなたの答えのための

<?xml version="1.0"?> 
<sample> 
    <tag a="1" b="2" c="3" d="4" e="5" f="6" g="7"/> 
    <tag a="2" b="3" c="4" d="5" e="10" f="12" g="11"/> 
</sample> 
0

まず、既存のノードをコピーするXSLT identity templateでオフに開始することで、物事を単純化することができます。そして、あなたの最初のXMLに

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

属性、tag要素に属性を追加するために、あなたが持っていますこの中tag

<xsl:template match="tag"> 

テンプレートマッチングでは、あなたは、現在の要素の位置を取得する必要があるので、あなたは、第二の同じ位置に関連するtag要素を見つけることができますその後

<xsl:variable name="position"> 
    <xsl:number /> 
</xsl:variable> 

文書は、あなたがそうのような第2の文書から属性を選択することができます。

<xsl:apply-templates select="document('xml2.xml')/sample/tag[position() = $position]/@*"/> 

短く、簡単な方法を適用する次のテンプレートを使用しているこのXSLT

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

    <xsl:template match="tag"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*"/> 
      <xsl:variable name="position"> 
       <xsl:number /> 
      </xsl:variable> 
      <xsl:apply-templates select="document('xml2.xml')/sample/tag[position() = $position]/@*"/> 
      <xsl:apply-templates select="node()"/> 
     </xsl:copy> 
    </xsl:template> 

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

感謝。 を避けるチャンスはありますか?私は本当に大きなXMLファイルのためにそれを使用しているので、が遅くなっています。しかし、XSLTはうまく機能します。 – tingelcore

+0

どのようにzx485の答えを参照してください。どのように明示的な ''があるかに注意してください。 'position()'は空白のノードや 'sample'の下の他の要素の影響を受けるため、これは必要です。 –

関連する問題