我目前正在研究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文件和:
与给定示例类似: 优先顺序:B3,B1,B2,B4。
就是这样,我知道这并不容易(我认为),所以我真的想了解如何编写一个实现上述所有内容的查询脚本。
非常非常感谢你能帮助我的人。
答案 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中执行此操作,最好每个输入文件执行一次查询,这意味着您需要使用某种外部语言的逻辑来迭代输入文件并为每个输入设置相应的输出文件。然后,您需要一个递归函数,它接受任何元素,如果它不是您要删除的元素之一,则创建一个具有相同名称的新元素,复制属性,并调用自身来处理子元素。所以它可以做到,但它还有很多工作要做。