我有以下xml:
<PCstore>
<StoreList>
<Store id="001">
<ItemList>
<Items laptop="DELL" price="300"/>
<Items laptop="gateway" price="450"/>
<Items screen="LG" price="200"/>
</ItemList>
</Store>
</StoreList>
</PCstore>
我必须合并:
<PCstore>
<StoreList>
<Store id="002">
<ItemList>
<Items laptop="gateway" price="650"/>
<Items screen="LG" price="200/>
<Items speakers="sony" price="50"/>
</ItemList>
</Store>
</StoreList>
</PCstore>
欲望输出ifiltering属性(laptop =“gateway”):
<PCstore>
<StoreList>
<Store id="001">
<ItemList>
<Items laptop="gateway" price="450"/>
</ItemList>
</Store>
<Store id="002">
<ItemList>
<Items laptop="gateway" price="650"/>
</ItemList>
</Store>
</StoreList>
</PCstore>
依此类推更多xml3.xml,xml4.xml 等...
我没有我尝试的代码,我在XSLT上有点新鲜,我希望有人可以帮助我。
更新:
我尝试了这段代码,但它没有用......
<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:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="Items">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
<xsl:apply-templates
select="document('xml2.xml')
/PCstore/StoreList/Store/ItemList[@id = current()/../@id]
/Items[@laptop = current()/@value]/*" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
答案 0 :(得分:1)
如果只能使用XSLT1.0,一种方法是将xml文件列表作为参数传递给XSLT。例如:
<xsl:param name="filelist">
<files>
<file>xml2.xml</file>
<!-- We can place here xml3.xml and so on -->
</files>
</xsl:param>
(因此,在这种情况下,我假设您将XSLT应用于第一个xml1.xml,并且您只传入任何其他文件作为参数)。
但是,在XSLT1.0中,您需要使用扩展函数将此参数作为节点集处理。执行<xsl:for-each select="$filelist/files/file">
将导致错误“对变量或参数'文件的引用'必须评估为节点列表。”。因此,您需要使用扩展函数将其转换为node-set。在我的示例中,我将使用Microsoft的示例,但根据您的平台,您可以使用exslt.org/common
在这种情况下,这是完整的XSLT
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxml="urn:schemas-microsoft-com:xslt"
extension-element-prefixes="msxml">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="filelist">
<files>
<file>xml2.xml</file>
</files>
</xsl:param>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="StoreList">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
<xsl:for-each select="msxml:node-set($filelist)/files/file">
<xsl:apply-templates select="document(text())/PCstore/StoreList/Store"/>
</xsl:for-each>
</xsl:copy>
</xsl:template>
<xsl:template match="Items[not(@laptop='gateway')]"/>
</xsl:stylesheet>
当应用于XSLT时,输出
<PCstore>
<StoreList>
<Store id="001">
<ItemList>
<Items laptop="gateway" price="450"/>
</ItemList>
</Store>
<Store id="002">
<ItemList>
<Items laptop="gateway" price="650"/>
</ItemList>
</Store>
</StoreList>
</PCstore>
请注意,必须存在文件才能使其正常工作。如果传入不存在的文件名,则会发生错误。
答案 1 :(得分:0)
如果您可以使用XSLT 2.0,则可以使用collection()
...
<强> xml1.xml 强>
<PCstore>
<StoreList>
<Store id="001">
<ItemList>
<Items laptop="DELL" price="300"/>
<Items laptop="gateway" price="450"/>
<Items screen="LG" price="200"/>
</ItemList>
</Store>
</StoreList>
</PCstore>
<强> xml2.xml 强>
<PCstore>
<StoreList>
<Store id="002">
<ItemList>
<Items laptop="gateway" price="650"/>
<Items screen="LG" price="200"/>
<Items speakers="sony" price="50"/>
</ItemList>
</Store>
</StoreList>
</PCstore>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:param name="type" select="'laptop'"/>
<xsl:param name="brand" select="'gateway'"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<PCstore>
<StoreList>
<xsl:apply-templates select="collection('file:///C:/store_test?select=*.xml')/PCstore/StoreList/Store"/>
</StoreList>
</PCstore>
</xsl:template>
<xsl:template match="Items[not(@*[name()=$type]=$brand)]"/>
</xsl:stylesheet>
<强>输出强>
<PCstore>
<StoreList>
<Store id="001">
<ItemList>
<Items laptop="gateway" price="450"/>
</ItemList>
</Store>
<Store id="002">
<ItemList>
<Items laptop="gateway" price="650"/>
</ItemList>
</Store>
</StoreList>
</PCstore>