2017-02-27 5 views
1

私はマージする必要がある2つのXMLドキュメントを持っています。すべての要素には定義済みのIDがあります。要素が両方の文書で一意である場合 - >結果に追加されますが、そうでない場合は - >属性がマージされます。 ELでXSLTは2つのドキュメントの要素の属性を結合します

main.xml

<main> 
    <el id="1" attr1="value1" /> 
    <el id="2" attr2="value2" default-attr="def" /> 
</main> 

snippet.xml

<main> 
    <el id="2" attr2="new value2" new-attr="some value" /> 
    <el id="3" attr3="value3" /> 
</main> 

result.xml

<main> 
    <el id="1" attr1="value1" /> 
    <el id="2" attr2="new value2" default-attr="def" new-attr="some value" /> 
    <el id="3" attr3="value3" /> 
</main> 

属性[@ id = 2]はマージされ、値はsnippet.xmlから上書きされます。

<?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:param name="snippetDoc" select="document(snippet.xml)" /> 

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

    <xsl:template match="el"> 
     <xsl:copy> 
      <!-- how to distinguish between @ids of two documents? --> 
      <xsl:copy-of select="$snippetDoc/main/el/[@id = @id]/@*" /> 
      <xsl:apply-templates select="@*" /> 
     </xsl:copy> 
    </xsl:template> 

</xsl:stylesheet> 

は、しかし、それは2つの文書に同じ属性を区別できるようにする必要があり

merge.xlst:

私はこれを試してみました。さらに、これはsnippet.xmlから一意の要素をコピーしません。

ありがとうございました!

答えて

1

また、あなたは新しい属性があれば書き込まれた既存の属性が上書きされるという事実を利用することができるように<xsl:apply-templates select="@*" />後にこれを置く必要がありますが、この探している表現....

<xsl:copy-of select="$snippetDoc/main/el[@id=current()/@id]/@*" /> 

彼ら同じ名前を持つ。

スニペットに、メイン文書に一致する要素がない要素を追加するには、main要素に一致するテンプレートでこれを行う必要があります。

<xsl:template match="main"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
      <xsl:copy-of select="$snippetDoc/main/el[not(@id=current()/el/@id)]" /> 
     </xsl:copy>  
    </xsl:template> 

node()*|text()|comment()|processing-instruction()のために実際に短い手ではとてもnode()|comment()を行うことは、実際に不要であることに注意してください、このXSLT

<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:param name="snippetDoc" select="document('snippet.xml')" /> 

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

    <xsl:template match="el"> 
     <xsl:copy> 
      <!-- how to distinguish between @ids of two documents? --> 
      <xsl:apply-templates select="@*" /> 
      <xsl:copy-of select="$snippetDoc/main/el[@id=current()/@id]/@*" /> 
     </xsl:copy> 
    </xsl:template> 

    <xsl:template match="main"> 
     <xsl:copy> 
      <xsl:apply-templates select="@*|node()"/> 
      <xsl:copy-of select="$snippetDoc/main/el[not(@id=current()/el/@id)]" /> 
     </xsl:copy>  
    </xsl:template> 

</xsl:stylesheet> 

を試してみてください。

関連する問題