首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使用匹配的节点连接两个XML文件

如何使用匹配的节点连接两个XML文件
EN

Stack Overflow用户
提问于 2011-06-16 05:04:52
回答 3查看 1.7K关注 0票数 7

当两个XML文件有匹配的节点时,我需要找到一种方法来连接它们。据我所知,这可以用许多不同的语言来完成……有没有一种PHP或AJAX的方法可以做到这一点?上的其他帖子中,我看到了XSLT解决方案。我真的不明白。这是最好/首选的方法吗?如果是这样的话,您知道有什么有用的XSLT教程吗?

例如,XML-1如下所示:

代码语言:javascript
复制
<FOO>
    </A>
    </B>
    </C>
    </D>
</FOO>

和XML-2:

代码语言:javascript
复制
<FOO>    
    </B>
    </E>
</FOO>

检查<B>==<B>位置然后添加<E>的最佳方法是什么

更新

好吧,我不能让我的假设的例子工作,我想我应该更新我正在做的事情,看看是否有人可以帮助我解决这个问题。我已经尝试了下面的方法和我在上面找到的其他方法,但都没有成功。

真正的模式如下:

file1.xml

代码语言:javascript
复制
<?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

代码语言:javascript
复制
<?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的节点,如下所示:

代码语言:javascript
复制
<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,如下所示:

代码语言:javascript
复制
<?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>

我还尝试了这样的合并:

代码语言:javascript
复制
<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对我来说是非常新的,所以我不确定我在做什么,我真的很感激在这方面做一些手把手。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-06-16 06:21:04

这是原始的转换,稍作修改以适应新的需求。合并是通过检查file2.xml元素执行的。对于file1中的当前项,如果file2中的子项不存在于中,则将仅合并中的子项。

XSLT 1.0

代码语言:javascript
复制
<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:variable name="input2" select="document('test_input2.xml')/DATA"/>

    <xsl:template match="node()|@*">
        <xsl:copy>
            <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ITEM">
        <xsl:variable name="item" select="
            $input2/ITEM[STYLE_COLOR=current()/STYLE_COLOR]"/>
        <xsl:variable name="ITEM" select="."/>

        <xsl:if test="$item">
            <xsl:copy>

                <xsl:for-each select="$item/*">
                    <xsl:if test="count($ITEM/*[name()=name(current())])=0">
                        <xsl:copy-of select="." />
                    </xsl:if>
                </xsl:for-each>

                <xsl:apply-templates select="*"/>
            </xsl:copy>
        </xsl:if>
    </xsl:template>

</xsl:stylesheet> 

应用于此input1.xml

代码语言:javascript
复制
<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>
  <ITEM>
    <PRODUCT_TYPE>simple</PRODUCT_TYPE>
    <STYLE_COLOR>1524740008</STYLE_COLOR>
    <SHORT_DESCRIPTION>Black Shoe</SHORT_DESCRIPTION>
    <CLASS_NAME>FOOTWEAR</CLASS_NAME>
    <STATUS>Disabled</STATUS>
  </ITEM>
  <ITEM>
    <PRODUCT_TYPE>simple</PRODUCT_TYPE>
    <STYLE_COLOR>777</STYLE_COLOR>
    <SHORT_DESCRIPTION>Black Shoe</SHORT_DESCRIPTION>
    <CLASS_NAME>FOOTWEAR</CLASS_NAME>
    <STATUS>Disabled</STATUS>
  </ITEM>
</DATA>

input2.xml进行合并,生成:

代码语言:javascript
复制
<DATA>
  <ITEM>
    <STYLE_COLOR>1524740007</STYLE_COLOR>
    <NEXT_ARRIVAL>2011-08-05</NEXT_ARRIVAL>
    <CLASS_NAME>XXX</CLASS_NAME>
    <OTHER>YYY</OTHER>
  </ITEM>
  <ITEM>
    <STYLE_COLOR>1524740008</STYLE_COLOR>
    <NEXT_ARRIVAL>2011-08-05</NEXT_ARRIVAL>
  </ITEM>
</DATA>

产生:

代码语言:javascript
复制
<DATA>
   <ITEM>
      <NEXT_ARRIVAL>2011-08-05</NEXT_ARRIVAL>
      <OTHER>YYY</OTHER>
      <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>
   <ITEM>
      <NEXT_ARRIVAL>2011-08-05</NEXT_ARRIVAL>
      <PRODUCT_TYPE>simple</PRODUCT_TYPE>
      <STYLE_COLOR>1524740008</STYLE_COLOR>
      <SHORT_DESCRIPTION>Black Shoe</SHORT_DESCRIPTION>
      <CLASS_NAME>FOOTWEAR</CLASS_NAME>
      <STATUS>Disabled</STATUS>
   </ITEM>
</DATA>

请注意:

  • 转换不会覆盖给定项的现有元素,仅复制缺少的元素。只有在input2.xml

中有匹配项时,才会在输出中复制input1.xml中的

票数 5
EN

Stack Overflow用户

发布于 2011-07-29 11:07:38

此转换 (c:/temp/file1.xmlc:/temp/file2.xml如问题所示):

代码语言:javascript
复制
<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:param name="pDoc1" select="'file:///c:/temp/file1.xml'"/>
 <xsl:variable name="vDoc1" select="document($pDoc1)"/>

 <xsl:param name="pDoc2" select="'file:///c:/temp/file2.xml'"/>
 <xsl:variable name="vDoc2" select="document($pDoc2)"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="/">
  <xsl:apply-templates select="$vDoc1/node()"/>
 </xsl:template>

 <xsl:template match="ITEM">
  <ITEM>
   <xsl:apply-templates/>

   <xsl:apply-templates select=
     "$vDoc2/*/ITEM
               [STYLE_COLOR = current()/STYLE_COLOR]
                /node()[not(self::STYLE_COLOR)]
     "/>
  </ITEM>
 </xsl:template>
</xsl:stylesheet>

当将应用于任何XML文档(不使用/忽略)时,都会生成所需的正确结果

代码语言:javascript
复制
<DATA>
   <ITEM xmlns:xs="http://www.w3.org/2001/XMLSchema">
      <PRODUCT_TYPE>simple</PRODUCT_TYPE>
      <STYLE_COLOR>1524740007</STYLE_COLOR>
      <SHORT_DESCRIPTION>Black Shoe</SHORT_DESCRIPTION>
      <CLASS_NAME>FOOTWEAR</CLASS_NAME>
      <STATUS>Disabled</STATUS>
      <NEXT_ARRIVAL>2011-08-05</NEXT_ARRIVAL>
   </ITEM> ...
</DATA>

说明

我们处理(将模板应用于)第一个

  1. First document.
  2. The身份规则/模板的节点复制每个节点,因为is.
  3. There是覆盖身份规则的单个模板。此模板可匹配任何名为ITEM的元素。它创建一个也名为ITEM的元素,然后处理所有子节点,这将导致通过身份模板复制它们。最后,作为第二个ITEM文档中任何STYLE_COLOR元素的子节点(其XML子元素的字符串值与当前(匹配的)元素的XML子元素的字符串值相同)也将被复制(通过对其应用模板,并作为选择和执行身份模板的结果),但XML子itself.
  4. Do除外。请注意,这两个STYLE_COLOR的文件路径作为参数传递给转换,这使得它更灵活,并且能够处理任何两个STYLE_COLOR文件,而无需任何修改。我们使用XSLT函数来加载和解析这两个文档,以便xslt transformation.
  5. Do可以处理它们。请注意,在此转换中没有使用 xsl:if或任何其他XSLT条件指令。这使得维护和理解code.
  6. Finally,变得更加简单和容易,注意身份规则/模板的使用和覆盖。这是最基础和最强大的XSLT设计pattern.

票数 1
EN

Stack Overflow用户

发布于 2011-06-16 05:24:42

XSLT非常强大,但是我必须承认我对它不太熟悉,所以我将建议您进行手动转换:

代码语言:javascript
复制
print "<FOOCONTAINER>\n";
readfile($xml1file);
readfile($xml2file);
print "</FOOCONTAINER>\n";

您可以在进一步处理中轻松完成的任何其他内容,因为这是XML。

XML:这只对OP提供的第一个有效。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6364362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档