質問
私は2つの類似したXMLファイルをマージする必要がありますが、一般的なタグ上のどの試合レコードのみ、次の例のe.g.<type>
ます:
file1.xml IS
<node>
<type>a</type>
<name>joe</name>
</node>
<node>
<type>b</type>
<name>sam</name>
</node>
file2.xml IS
<node>
<type>a</type>
<name>jill</name>
</node>
私は
の出力を持っているように、<node>
<type>a</type>
<name>jill</name>
<name>joe</name>
</node>
<node>
<type>b</type>
<name>sam</name>
</node>
XSLで、これを行うの基本は何ですか? 多くのおかげます。
解決
このスタイルシートます:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kElementByType" match="*[not(self::type)]" use="../type"/>
<xsl:param name="pSource2" select="'file2.xml'"/>
<xsl:variable name="vSource2" select="document($pSource2,/)"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="type">
<xsl:variable name="vCurrent" select="."/>
<xsl:call-template name="identity"/>
<xsl:for-each select="$vSource2">
<xsl:apply-templates select="key('kElementByType',$vCurrent)"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
この入力(WELLFORMED)で
<root>
<node>
<type>a</type>
<name>joe</name>
</node>
<node>
<type>b</type>
<name>sam</name>
</node>
</root>
出力:
<root>
<node>
<type>a</type>
<name>jill</name>
<name>joe</name>
</node>
<node>
<type>b</type>
<name>sam</name>
</node>
</root>
他のヒント
私は場合には、それは他の初心者への使用のためです、それだけの価値はこれをやっている間、私が学んだいくつかの余分な情報を追加すると思いました。彼らは潜在的にXSLで使用される用語の一部と混同されないように、私は私のテストコード名を変更しました。私はそれが物事の最善あるいは最も効率的な方法だ場合はさっぱりだが、それは動作します(いくつかの注意事項に!)。
私は「情報」ノードを維持したい、と元のコードは、それを失いました。別の試合のテンプレートをコーディングすると、出力でそれを保持します。それは、入力ファイル(X1)である場合にも、私はそれをコード化された方法は、このノードにのみ保持されます。それは(×2)ファイルの中なら、それは保持されません。これは私が反復を書いた方法でなければなりません。理想的には、私はどちらかの入力ファイルからそれを維持したいのですが、まだどのように行うかは働いていません。また、私はmsxslを経由して、パラメータとしてファイル名×2を渡すためのオプションを持っているしたいのではなく、それは、ハードコーディングされています。確かにそこにこれを行う方法でなければなりませんが、私はまだそれを追跡するために管理していない。
XSLファイルます:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:key name="kElementByType" match="*[not(self::keynode)]" use="../keynode"/>
<xsl:param name="pSource2" select="'x2.xml'"/>
<xsl:variable name="vSource2" select="document($pSource2,/)"/>
<xsl:template match="node()|@*" name="identity">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="info">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="keynode">
<xsl:variable name="vCurrent" select="."/>
<xsl:call-template name="identity"/>
<xsl:for-each select="$vSource2">
<xsl:apply-templates select="key('kElementByType',$vCurrent)"/>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
だから、msxlsコマンドを使用します:
msxsl.exe x1.xml test.xsl -o out.xml
の下のデータと、次の結果が得られます:
ファイルx1.xmlます:
<root>
<info>
<id>147</id>
</info>
<nodetype>
<keynode>annajon</keynode>
<note>
<source>source1</source>
<name>Anna Jones</name>
</note>
</nodetype>
<nodetype>
<keynode>brucejon</keynode>
<note>
<source>source1</source>
<name>Bruce Jones</name>
</note>
</nodetype>
</root>
ファイルx2.xmlます:
<root>
<nodetype>
<keynode>annajon</keynode>
<note>
<source>source2</source>
<name>Anna Jones</name>
</note>
</nodetype>
<nodetype>
<keynode>iangore</keynode>
<note>
<source>source2</source>
<name>Ian Gore</name>
</note>
</nodetype>
</root>
out.xmlます:
<?xml version="1.0" encoding="UTF-16"?><root>
<info>
<id>147</id>
</info>
<nodetype>
<keynode>annajon</keynode><note>
<source>source2</source>
<name>Anna Jones</name>
</note>
<note>
<source>source1</source>
<name>Anna Jones</name>
</note>
</nodetype>
<nodetype>
<keynode>brucejon</keynode>
<note>
<source>source1</source>
<name>Bruce Jones</name>
</note>
</nodetype>
</root>
は一つの方法は、パラメータとして第二XMLを渡すことで、
第二の簡単な方法は、
に1つのルート要素の下の両方XMLSを連結することです<root>
<node>
<type>a</type>
<name>joe</name>
</node>
<node>
<type>b</type>
<name>sam</name>
</node>
<node>
<type>a</type>
<name>jill</name>
</node>
</root>
その後、と2を使用して、それをマージします
<xsl:template match="/root">
<xsl:for-each select="node">
<xsl:variable name="type" select="type"/>
<node>
<type><xsl:value-of select="$type"/></type>
<xsl:for-each select="../node[type=$type]">
<name><xsl:value-of select"name"/></name>
</xsl:for-each>
</node>
</xsl:for-each>
</xsl:template>