【发布时间】:2011-09-15 21:37:34
【问题描述】:
当两个 XML 文件有一个匹配的节点时,我需要找到一种方法来连接它们。据我所知,这可以用许多不同的语言来完成......是否有 PHP 或 AJAX 方式来做到这一点?从 SO 上的其他帖子中,我看到了 XSLT 解决方案.. 我真的不明白。这是最好/首选的方法吗?如果有,知道任何有用的 XSLT 教程吗?
例如 XML-1 是这样的:
<FOO>
</A>
</B>
</C>
</D>
</FOO>
和 XML-2 :
<FOO>
</B>
</E>
</FOO>
检查<B>==<B> 的位置然后添加<E> 的最佳方法是什么
更新
好吧,我无法让这个与我假设的例子一起工作,我想我会更新我真正在做什么,看看是否有人可以帮助我解决这个问题。我已经尝试了下面的方法以及我在 SO 上找到的其他方法,但都没有运气。
真正的架构是这样的:
file1.xml
<?xml version="1.0"?>
<DATA>
<ITEM>
<PRODUCT_TYPE>simple</PRODUCT_TYPE>
<STYLE_COLOR>1524740007</STYLE_COLOR>
<SHORT_DESCRIPTION>Black Shoe</SHORT_DESCRIPTION>
<CLASS_NAME>FOOTWEAR</CLASS_NAME>
<STATUS>Disabled</STATUS>
</ITEM>
...
</DATA>
file2.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="merge.xsl" ?>
<DATA>
<ITEM>
<STYLE_COLOR>1524740007</STYLE_COLOR>
<NEXT_ARRIVAL>2011-08-05</NEXT_ARRIVAL>
</ITEM>
....
</DATA>
我需要弄清楚的是生成一个新的 XML 文件,它将这些节点与相同的 SYTLE_COLOR 合并,看起来像:
<DATA>
<ITEM>
<PRODUCT_TYPE>simple</PRODUCT_TYPE>
<STYLE_COLOR>1524740007</STYLE_COLOR>
<SHORT_DESCRIPTION>Black Shoe</SHORT_DESCRIPTION>
<CLASS_NAME>FOOTWEAR</CLASS_NAME>
<NEXT_ARRIVAL>2011-08-05</NEXT_ARRIVAL>
<STATUS>Disabled</STATUS>
</ITEM>
我尝试创建一个如下所示的 merge.xsl:
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:transform version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="ISO-8859-1" indent="yes" />
<xsl:output indent="yes"/>
<xsl:variable name="with" select="'file-2.xml'" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="scene">
<xsl:copy>
<xsl:apply-templates select="@*|node()" />
<xsl:variable name="info" select="document($with)/DATA/ITEM[STYLE_COLOR=current()/STYLE_COLOR]/." />
<xsl:for-each select="$info/*">
<xsl:if test="name()!='STYLE_COLOR'">
<xsl:copy-of select="." />
</xsl:if>
</xsl:for-each>
</xsl:copy>
</xsl:template>
</xsl:transform>
我也尝试过这样的合并:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:variable name="input2" select="document('file-2.xml')/DATA/ITEM"/>
<xsl:template match="STYLE_COLOR">
<xsl:copy>
<xsl:apply-templates select="*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="*">
<xsl:choose>
<xsl:when test="$input2/*[name()=name(current())]">
<xsl:copy-of select="$input2/*"/>
</xsl:when>
<xsl:otherwise>
<xsl:copy-of select="."/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
这些方法都不起作用.. 抱歉 XSLT 对我来说很新,所以我不确定我在做什么,真的很感激有人握着这个方法。
【问题讨论】:
-
XSLT 是一种方法。 “这是最好/首选的方法吗?”这取决于您的经验和您的要求。你的xml真的那么简单吗??
-
标签的顺序重要吗?比如
D一定要放在最后? -
请同时指出您可以考虑的 XSLT 版本。
-
标签的顺序并不重要..我想我必须使用1.0
-
好问题,+1。请参阅我的答案以获取一个非常简单的解决方案,该解决方案也是参数化且灵活的。该解决方案使用 XSLT
document()函数,也是基于最基础和最强大的 XSLT 设计模式。答案末尾有详细说明。