Php 如何使用XSL跨两个或多个XML文件组合子节点?
我正在尝试使用XSL组合XML文件。我已经在stackoverflow、谷歌和其他网站上找到了线索。我发现了类似的问题或主题,但没有一个完全符合我的意图 我试着利用我从这些资源中收集到的信息,但我似乎没有得到我想要的结果。所以…到S/O进行快速咨询 以下是我目前的做法: 输入文件1.xmlPhp 如何使用XSL跨两个或多个XML文件组合子节点?,php,xml,xslt,Php,Xml,Xslt,我正在尝试使用XSL组合XML文件。我已经在stackoverflow、谷歌和其他网站上找到了线索。我发现了类似的问题或主题,但没有一个完全符合我的意图 我试着利用我从这些资源中收集到的信息,但我似乎没有得到我想要的结果。所以…到S/O进行快速咨询 以下是我目前的做法: 输入文件1.xml <?xml version="1.0" encoding="UTF-8"?> <protocol> <message_exchanges> <messag
<?xml version="1.0" encoding="UTF-8"?>
<protocol>
<message_exchanges>
<message_exchange id="1"/>
<message_exchange id="2"/>
</message_exchanges>
<message_types>
<message_type id="1"/>
<message_type id="2"/>
<message_type id="3"/>
</message_types>
</protocol>
输入文件2.xml
<?xml version="1.0" encoding="UTF-8"?>
<protocol>
<message_exchanges>
<message_exchange id="3"/>
<message_exchange id="4"/>
</message_exchanges>
<message_types>
<message_type id="4"/>
<message_type id="5"/>
<message_type id="6"/>
</message_types>
</protocol>
Input index.xml
<?xml version="1.0" encoding="UTF-8"?>
<index>
<component>file1.xml</component>
<component>file2.xml</component>
</index>
file1.xml
file2.xml
combine.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" indent="yes"/>
<xsl:template match="index">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="component">
<xsl:apply-templates select="document(.)"/>
</xsl:template>
.....help me fix / finish this file
</xsl:stylesheet>
…请帮助我修复/完成此文件
所需的_result.xml
<?xml version="1.0" encoding="UTF-8"?>
<protocol>
<message_exchanges>
<message_exchange id="1"/>
<message_exchange id="2"/>
<message_exchange id="3"/>
<message_exchange id="4"/>
</message_exchanges>
<message_types>
<message_type id="1"/>
<message_type id="2"/>
<message_type id="3"/>
<message_type id="4"/>
<message_type id="5"/>
<message_type id="6"/>
</message_types>
</protocol>
1000点奖励积分,如果您可以帮助我在飞行中添加属性:
<message_type id="1" src="file1.xml"/>
<message_type id="4" src="file2.xml"/>
我正在使用PHP的XSLTProcessor加载XSL文件并将其应用于XML索引文件,因此,如果添加src
属性有助于/更容易实现,我可以将源文件名作为参数加载到处理器中
谢谢!如果我能进一步澄清,请告诉我
在这种情况下,模板参数变得非常有用。这是我实际能够产生的最短最简单的变换它处理两个或多个文件。
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:template match="index">
<protocol>
<message_exchanges>
<xsl:apply-templates select="component">
<xsl:with-param name="message" select="'message_exchanges'"/>
</xsl:apply-templates>
</message_exchanges>
<message_types>
<xsl:apply-templates select="component">
<xsl:with-param name="message" select="'message_types'"/>
</xsl:apply-templates>
</message_types>
</protocol>
</xsl:template>
<xsl:template match="component">
<xsl:param name="message"/>
<xsl:apply-templates select="document(.)/*/*[name()=$message]/*">
<xsl:with-param name="comp" select="."/>
</xsl:apply-templates>
</xsl:template>
<xsl:template match="message_type|message_exchange">
<xsl:param name="comp" select="''"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="src">
<xsl:value-of select="$comp"/>
</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
输出:
<protocol>
<message_exchanges>
<message_exchange id="1" src="file1.xml"/>
<message_exchange id="2" src="file1.xml"/>
<message_exchange id="3" src="file2.xml"/>
<message_exchange id="4" src="file2.xml"/>
</message_exchanges>
<message_types>
<message_type id="1" src="file1.xml"/>
<message_type id="2" src="file1.xml"/>
<message_type id="3" src="file1.xml"/>
<message_type id="4" src="file2.xml"/>
<message_type id="5" src="file2.xml"/>
<message_type id="6" src="file2.xml"/>
</message_types>
</protocol>
此转换:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vFilename1" select="/*/component[1]"/>
<xsl:variable name="vFilename2" select="/*/component[2]"/>
<xsl:template match="index">
<protocol>
<xsl:apply-templates select="document($vFilename1)"/>
</protocol>
</xsl:template>
<xsl:template match="message_exchanges|message_types">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select=
"document($vFilename2)/*/*[name()=name(current())]/*">
<xsl:with-param name="pFilename" select="$vFilename2"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="message_exchanges/* | message_types/*">
<xsl:param name="pFilename" select="$vFilename1"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="src">
<xsl:value-of select="$pFilename"/>
</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<index>
<component>file1.xml</component>
<component>file2.xml</component>
</index>
<protocol>
<message_exchanges>
<message_exchange id="1" src="file1.xml"/>
<message_exchange id="2" src="file1.xml"/>
<message_exchange id="3" src="file2.xml"/>
<message_exchange id="4" src="file2.xml"/>
</message_exchanges>
<message_types>
<message_type id="1" src="file1.xml"/>
<message_type id="2" src="file1.xml"/>
<message_type id="3" src="file1.xml"/>
<message_type id="4" src="file2.xml"/>
<message_type id="5" src="file2.xml"/>
<message_type id="6" src="file2.xml"/>
</message_types>
</protocol>
应用于提供的XML文档时:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vFilename1" select="/*/component[1]"/>
<xsl:variable name="vFilename2" select="/*/component[2]"/>
<xsl:template match="index">
<protocol>
<xsl:apply-templates select="document($vFilename1)"/>
</protocol>
</xsl:template>
<xsl:template match="message_exchanges|message_types">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select=
"document($vFilename2)/*/*[name()=name(current())]/*">
<xsl:with-param name="pFilename" select="$vFilename2"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="message_exchanges/* | message_types/*">
<xsl:param name="pFilename" select="$vFilename1"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="src">
<xsl:value-of select="$pFilename"/>
</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<index>
<component>file1.xml</component>
<component>file2.xml</component>
</index>
<protocol>
<message_exchanges>
<message_exchange id="1" src="file1.xml"/>
<message_exchange id="2" src="file1.xml"/>
<message_exchange id="3" src="file2.xml"/>
<message_exchange id="4" src="file2.xml"/>
</message_exchanges>
<message_types>
<message_type id="1" src="file1.xml"/>
<message_type id="2" src="file1.xml"/>
<message_type id="3" src="file1.xml"/>
<message_type id="4" src="file2.xml"/>
<message_type id="5" src="file2.xml"/>
<message_type id="6" src="file2.xml"/>
</message_types>
</protocol>
file1.xml
file2.xml
生成所需的正确结果:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:variable name="vFilename1" select="/*/component[1]"/>
<xsl:variable name="vFilename2" select="/*/component[2]"/>
<xsl:template match="index">
<protocol>
<xsl:apply-templates select="document($vFilename1)"/>
</protocol>
</xsl:template>
<xsl:template match="message_exchanges|message_types">
<xsl:copy>
<xsl:apply-templates/>
<xsl:apply-templates select=
"document($vFilename2)/*/*[name()=name(current())]/*">
<xsl:with-param name="pFilename" select="$vFilename2"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<xsl:template match="message_exchanges/* | message_types/*">
<xsl:param name="pFilename" select="$vFilename1"/>
<xsl:copy>
<xsl:copy-of select="@*"/>
<xsl:attribute name="src">
<xsl:value-of select="$pFilename"/>
</xsl:attribute>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<index>
<component>file1.xml</component>
<component>file2.xml</component>
</index>
<protocol>
<message_exchanges>
<message_exchange id="1" src="file1.xml"/>
<message_exchange id="2" src="file1.xml"/>
<message_exchange id="3" src="file2.xml"/>
<message_exchange id="4" src="file2.xml"/>
</message_exchanges>
<message_types>
<message_type id="1" src="file1.xml"/>
<message_type id="2" src="file1.xml"/>
<message_type id="3" src="file1.xml"/>
<message_type id="4" src="file2.xml"/>
<message_type id="5" src="file2.xml"/>
<message_type id="6" src="file2.xml"/>
</message_types>
</protocol>
Oops,不,不是故意的。现在修好了。问得好,+1。请参阅我的答案,以获得一个相当简短、通用且简单的解决方案。问题实际上是问“如何使用XSL在两个或多个XML文件中组合子节点?”@empo,以及您的评论与我的答案之间的关系如何?您似乎已经展示了如何在两个特定的XML文件中组合子节点。如果您有100个文件要合并,则显示的转换不是很有用。请参阅我的答案以获得更一般的解决方案。@empo,是的,这就是OP想要的。有很多可能的概括,假设的时间不长。标题要求提供“两个或更多”文件。感谢您的回答,并感谢您将其设计为处理可变数量的输入文件(这确实是我想要的)。