【问题标题】:Merge then sort two xml files合并然后排序两个xml文件
【发布时间】:2014-02-16 07:53:26
【问题描述】:

我已经搜索过这个问题的答案,坦率地说,我想出了这么多可能的答案,以至于我不知所措,所以我仍然不确定如何继续。

我有两个 XML 文件,我想将它们合并在一起,然后根据三个不同的标准进行排序。

当然,每个文件都具有相同的结构:

<root>
    <item>
        <number>1</number>
        <name>Name</name>
        <time>6h</time>
        <internal>NAME_01</internal>
        <flag>0</flag>
    </item>
</root>

我只是想将这两个文件合并在一起然后排序。排序需要按这样的顺序进行:

  • 标志(这可以是 0 或 1。0 会先出现。)
  • 数字(从 1 到 20 的简单数字。将首先排序最低。)
  • 姓名(简单的字母顺序。)

我已经看到了很多关于使用 XSLT 的建议,但我对此一无所知。我不反对使用它,只要我得到一些关于如何实施它的说明。不过,它不一定是 XSLT。我愿意接受任何选择,简单是关键。可以为我做到这一点的免费应用程序(可下载或基于网络)将是我的圣杯。

可接受的排序示例如下:

<root>
    <item>
        <number>1</number>
        <name>Apple</name>
        <time>6h</time>
        <internal>FRUIT_APPLE_01</internal>
        <flag>0</flag>
    </item>
    <item>
        <number>1</number>
        <name>Banana</name>
        <time>2h</time>
        <internal>FRUIT_BANANA_01</internal>
        <flag>0</flag>
    </item>
    <item>
        <number>4</number>
        <name>Cabbage</name>
        <time>1h 15m</time>
        <internal>VEGETABLE_CABBAGE_02</internal>
        <flag>0</flag>
    </item>
    <item>
        <number>4</number>
        <name>Cucumber</name>
        <time>25m</time>
        <internal>FRUIT_CUCUMBER_01</internal>
        <flag>0</flag>
    </item>
    <item>
        <number>12</number>
        <name>Avocado</name>
        <time>12h</time>
        <internal>FRUIT_AVOCADO_03</internal>
        <flag>0</flag>
    </item>
    <item>
        <number>3</number>
        <name>Cat</name>
        <time>6h</time>
        <internal>MAMMAL_01</internal>
        <flag>1</flag>
    </item>
    <item>
        <number>8</number>
        <name>Iguana</name>
        <time>1h</time>
        <internal>REPTILE_04</internal>
        <flag>1</flag>
    </item>
</root>

如果我能澄清任何事情,请告诉我。

非常感谢。

【问题讨论】:

    标签: xml sorting xslt merge


    【解决方案1】:

    假设您的文件中没有重复文件,这实际上并没有那么复杂。

    由于您根本不转换 item 元素,因此您首先使用标识模板

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

    然后,您只需要编写一个模板来匹配(第一个 XML 文档的)root 元素,因为您将通过添加和重新排序其子节点来更改它。 p>

    在合并方面,只需要写一个xsl:apply-templates来选择当前root元素的item元素,然后第二个 XML 文件中的 item 元素。这可以与 xsl:sort 指令结合使用。

         <xsl:apply-templates select="item|document($mergeFile)/root/item">
            <xsl:sort select="flag" />
            <xsl:sort select="number" data-type="number" />
            <xsl:sort select="name" />
         </xsl:apply-templates>
    

    注意使用 document 函数来读取第二个 XML 文件。在这种情况下,$mergeFile 是一个参数,设置为您希望与 XML 当前正在处理的第一个文件合并的第二个文件的位置。

    就是这样!试试这个 XSLT

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
       <xsl:output method="xml" indent="yes"/>
       <xsl:param name="mergeFile" select="'Test2.xml'" />
    
       <xsl:template match="/*">
          <xsl:copy>
             <xsl:apply-templates select="item|document($mergeFile)/root/item">
                <xsl:sort select="flag" />
                <xsl:sort select="number" data-type="number" />
                <xsl:sort select="name" />
             </xsl:apply-templates>
          </xsl:copy>
       </xsl:template>
    
       <xsl:template match="@*|node()">
          <xsl:copy>
             <xsl:apply-templates select="@*|node()"/>
          </xsl:copy>
       </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 首先,感谢您对我的回应,而不是像其他人似乎所做的那样投反对票并继续前进。遍布stackoverflow的downvote巨魔是我犹豫在这里发布的原因之一。其次,您能解释一下我将如何执行上述脚本吗?我已经找到了方法,但它们似乎只适用于一个文件。我不确定如何传递第二个文件。
    • 上述脚本的执行方式有很多种,具体取决于你使用的平台。 C#、php、Java、JavaScript 等。虽然此过程最初需要您将 XSLT 应用于单个文件,但“文档”功能允许它访问另一个文件。您实际上并没有传递第二个文件本身,而是传递了文件名(可能带有它位于另一个目录中的完整文件路径)。因此,最好查找如何将参数传递给 XSLT 以用于您正在使用的方法。
    • 这里以 C# 传递参数为例。 stackoverflow.com/questions/1521064/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-05
    • 2023-03-18
    • 1970-01-01
    • 2019-04-29
    相关资源
    最近更新 更多