Я подумал, что стоит добавить некоторую дополнительную информацию, которую я узнал во время этой работы, на случай, если она пригодится другим новичкам. Я изменил имена тестовых кодов, чтобы их не перепутали с некоторыми терминами, используемыми в xsl. Я понятия не имею, является ли это лучшим или наиболее эффективным способом ведения дел, но он работает (с несколькими оговорками!).
Я хотел сохранить узел "info", а исходный код потерял его. Кодирование отдельного шаблона соответствия сохраняет его в выходных данных. Кроме того, как я его кодировал, этот узел сохраняется, только если он находится во входном файле (x1). Если он находится в файле (x2), он не сохраняется. Это должно быть так, как я написал итерации. В идеале я хотел бы сохранить его в любом из входных файлов, но пока не выяснил, как это сделать. Кроме того, я хотел бы иметь возможность передавать имя файла x2 в качестве параметра через msxsl, а не жестко его кодировать. Конечно, должен быть способ сделать это, но мне пока не удалось его отследить.
xsl file:
<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>