【问题标题】:Merge two xml with substring as key合并两个以子字符串为键的xml
【发布时间】:2022-12-08 23:03:45
【问题描述】:

我有两个 XML 文件。

第一个 XML

<annunci>
    <annuncio>
        <any_info>222</any_info>
        <reference>333</reference>
                .
                .
                <lot_of_info> </lot_of_info>
                .
                .
        <some_info>1</some_info>
     <images>
    
    </images>
</annuncio>

第二个 XML

<images>
    <img>       
        <url>http://example.com/xml/img/333/somefile</url>
        <type>0</type>
        <public>1</public>
        <share>1</share>
    </img>

      <img>     
        <url>http://example.com/xml-feed/img/333/somefile</url>
        <type>0</type>
        <public>1</public>
        <share>1</share>
    </img>

</images>

使用第一个文件 <reference>(示例:333)和第二个文件的 <url> 合并两个 XML,子字符串(文件夹)具有相同的编号(例如:https://example.com/xml-feed/img/333/file1https://example.com/xml-feed/img/333/file2),以获得最终的 XML,如下所示:

<annunci>
    <annuncio>
            <any_info>222</any_info>
        <reference>333</reference>
                .
                .
                <lot_of_info> </lot_of_info>
                .
                .
        <some_info>1</some_info>
     <images>
<img>       
        <url>http://example.com/xml/img/333/file1</url>
        <type>0</type>
        <public>1</public>
        <share>1</share>
    </img>

      <img>     
        <url>http://example.com/xml-feed/img/333/file2</url>
        <type>0</type>
        <public>1</public>
        <share>1</share>
    </img>
     </images>
</annuncio>

我尝试这个但没有运气:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    
    <!-- identity template: copies all nodes and attributes as-is -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    
    <!-- template to add the <img> elements from the second XML file -->
    <xsl:template match="/annunci/annuncio/images">
        <xsl:copy>
  
            <!-- add the <img> elements from the second XML file that have a matching <url> -->
            <xsl:for-each select="document('second.xml')/images/img[contains(url, /annunci/annuncio/reference)]">
                <xsl:copy-of select="."/>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

因为我只需要复制...与 annuncio/annunci/images 中匹配的 URL

【问题讨论】:

  • 问题是我在 output.xml 上有所有 img 节点,而不仅仅是匹配的节点。

标签: xml xslt xml-parsing xslt-2.0


【解决方案1】:

我会使用密钥&lt;xsl:key name="ref" match="images/img" use="tokenize(url, '/')[last() - 1]"/&gt; 然后例如

<xsl:template match="/annunci/annuncio/images">
    <xsl:copy>
       <xsl:copy-of select="key('ref', ../reference, doc('second.xml'))"/>
    </xsl:copy>
</xsl:template>

【讨论】:

  • 不是很明白,能再解释一下吗?
  • @Ugo,我不确定您希望我解释什么,xsl:key 是您作为xsl:stylesheet 的子项放置的顶级声明。它告诉 XSLT 处理器通过 url 子元素的倒数第二个标记(我认为是那个数字,例如 333)来索引 images 元素中的 img 元素。然后 key('ref', ../reference, doc('second.xml')) 使用 annuncio/images 模板中的键和 key 函数从第二个文档中提取引用的 img 元素。
【解决方案2】:

您可以将第二个模板修改为:

<!-- template to add the <img> elements from the second XML file -->
    <xsl:template match="images">
        <xsl:variable name="ref" select="../reference"/>
        <xsl:copy>
            <!-- add the <img> elements from the second XML file that have a matching <url> -->
            <xsl:for-each select="document('second.xml')/images/img[contains(url, $ref)]">
                <xsl:copy-of select="."/>
            </xsl:for-each>
        </xsl:copy>
    </xsl:template>

(尽管正如另一个答案中指出的那样,使用键进行查找是最佳做法。)

为确保您不匹配 URL 中引用 ID 的子模式,您可以执行以下操作:

<xsl:for-each select="document('second.xml')/images/img[contains(url, concat('/',$ref,'/'))]">

【讨论】:

  • 请注意,给定&lt;reference&gt;333&lt;/reference&gt;,这还将复制img&lt;url&gt;http://example.com/xml/img/3334/file1&lt;/url&gt;。如果您更了解您要查找的内容,请使用它。
  • 但是我在 output.xml 上遇到了同样的问题,结果是所有 img 节点而不仅仅是匹配的节点。
  • 您的示例仅包含一个参考,两个图像与该参考匹配,因此很难知道您的完整数据是什么样的。
  • 对不起,你是对的。我得到了很多 img,有些匹配,有些不匹配。我需要在第一个文件上合并在线匹配
  • 我已经更新了我的答案(“ref”变量中的选择是错误的)。
猜你喜欢
  • 2017-06-14
  • 1970-01-01
  • 2011-03-13
  • 2018-10-09
  • 2011-03-25
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 2017-10-25
相关资源
最近更新 更多