实现

时间:2017-01-19 13:50:39

标签: xml xquery

我目前正在研究xQuery语言,而我正在做一些练习,我发现了一个我无法做到的查询。我真的希望你能帮助我。

我有n个已排序的文件,这些文件在" value"中有相同的节点但值不同。属性,就像那个:

<?xml version="1.0" encoding="UTF-8"?>
<root>
    <source name="File1.txt">
        <line nr="1" value="13" />
        <line nr="2" value="10" />
        <line nr="3" value="5" />
    </source>
    <source name="File2.txt">
        <line nr="1" value="2" />
    </source>
</root>

我必须编写一个获取所有源标记的xquery,并且对于每个源标记,它将删除value属性小于10的行。

在这种情况下,结果将是:

<?xml version="1.0" encoding="UTF-8"?>
    <root>
        <source name="File1.txt">
            <line nr="1" value="13" />
            <line nr="2" value="10" />
        </source>
        <source name="File2.txt" />
    </root>

因此,对于每个xml文件,我将生成一个新文件,如上所述,我将调用&#34; B&#34;。

现在,我必须创建一个查询,该查询将创建一个新的唯一xml文件(我称之为C),其中包含以下内容:假设每个B文件都有优先级(es:B12&gt; B10&gt; B8&gt; ...),我必须按顺序打开B文件和:

  1. 如果C中缺少源节点,请将其复制到内部。
  2. 对于每个行节点,添加一个名为&#34; pos&#34;的新属性。这将代表B文件优先级排序中包含该行的第一个B文件在该源节点内的位置。
  3. 与给定示例类似: 优先顺序:B3,B1,B2,B4。

    • 打开B3,对于每个源节点,将其复制到C文件中(它是第一个,所以它只是复制它们)
      • 对于该源节点内的每个行节点,复制所有行(它是第一行,所以我将只复制它们)并添加属性&#34; pos&#34;每行的值为1(优先级内B3的位置)。
    • 打开B1,对于每个源节点,如果C文件中缺少这个,请将其复制到C文件中。
      • 对于该源节点内的每个行节点,复制所有缺失的行并添加属性&#34; pos&#34;价值2。
    • 打开B2,对于每个源节点,如果C文件中缺少这个,请将其复制到C文件中。
      • 对于该源节点内的每个行节点,复制所有缺失的行并添加属性&#34; pos&#34;价值3。
    • 打开B4,对于每个源节点,如果C文件中缺少这个,请将其复制到C文件中。
      • 对于该源节点内的每个行节点,复制所有缺失的行并添加属性&#34; pos&#34;价值4。

    就是这样,我知道这并不容易(我认为),所以我真的想了解如何编写一个实现上述所有内容的查询脚本。

    非常非常感谢你能帮助我的人。

1 个答案:

答案 0 :(得分:1)

使用XSLT实际上更容易做出输出只有输入的微小变化的查询类型。此外,XSLT能够在单次执行期间生成多个输出文件,这在XQuery中是不可能的。在XSLT 3.0中,这可能是:

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0">

<xsl:mode on-no-match="shallow-copy"/>

<xsl:template match="line[@value lt 10]"/>

<xsl:template name="xsl:initial-template">
  <xsl:for-each select="collection('file:///input-dir')">
    <xsl:result-document href="{tokenize(document-uri(.), '/')[last()]}">
      <xsl:apply-templates/>
    </xsl:result-document>
  </xsl:for-each>
</xsl:template>

要在XQuery中执行此操作,最好每个输入文件执行一次查询,这意味着您需要使用某种外部语言的逻辑来迭代输入文件并为每个输入设置相应的输出文件。然后,您需要一个递归函数,它接受任何元素,如果它不是您要删除的元素之一,则创建一个具有相同名称的新元素,复制属性,并调用自身来处理子元素。所以它可以做到,但它还有很多工作要做。