如何限制XQuery结果中的返回顺序?

时间:2016-02-16 02:33:04

标签: xml xpath xquery basex

这是新手问题。我最近刚开始学习XQuery和XPath。

考虑这个XML

<employees>
    <employee empid="1">
        <ename>KING</ename>
        <mgr></mgr>
        <hiredate>17-11-1981</hiredate>
    </employee>
    <employee empid="2">
        <ename>BLAKE</ename>
        <mgr>7839</mgr>
        <hiredate>1-5-1981</hiredate>
        <test>
            <sub1>one</sub1>
            <sub2>two</sub2>
        </test>
    </employee>
</employees>

当我执行以下XQuery时,

let $db := db:open("example", "documents/employee.xml")
for $item in $db/(/employees/employee,/employees/employee/test)
let $empid := $item/@empid
let $ename := $item/ename
let $sub1 := $item/sub1
let $hiredate := $item/hiredate
let $sub2 := $item/sub2
return ($empid,$ename,$sub1,$hiredate,$sub2)

我得到了......

empid="1"
<ename>KING</ename>
<hiredate>17-11-1981</hiredate>
<sub1>empid1-one</sub1>
empid="2"
<ename>BLAKE</ename>
<hiredate>1-5-1981</hiredate>
<sub1>empid2-one</sub1>
<sub2>empid2-two</sub2>

我希望得到的结果是......

empid="1"
<ename>KING</ename>
<sub1>empid1-one</sub1>
<hiredate>17-11-1981</hiredate>
empid="2"
<ename>BLAKE</ename>
<sub1>empid2-one</sub1>
<hiredate>1-5-1981</hiredate>
<sub2>empid2-two</sub2>

我希望结果顺序基于我的return子句的顺序。

有人可以指出我正确的方向吗?感谢

2 个答案:

答案 0 :(得分:1)

实际上,XQuery并没有改变你指定的返回值的顺序。您观察到的是由于您的代码在循环遍历employee元素之前首先通过所有test元素循环,通过说in $db/(/employees/employee,/employees/employee/test)

假设一个employee只有一个test孩子,您可以尝试这种方式:

let $db := db:open("example", "documents/employee.xml")
for $item in $db/employees/employee
let $empid := $item/@empid
let $ename := $item/ename
let $sub1 := $item/test/sub1
let $hiredate := $item/hiredate
let $sub2 := $item/test/sub2
return ($empid,$ename,$sub1,$hiredate,$sub2)

答案 1 :(得分:1)

har07已经给出了一个很好的答案,接受这个答案,而不是我的答案。同样,如果没有父元素,则无法输出属性节点。您可以像这样更改属性变量:

let $empid := $item/@empid/concat(name(), '=', ., '&#10;')

如果你关心换行符而不仅仅是空白行:

let $empid := $item/@empid/concat('&#10;',name(), '=', ., '&#10;')

,输出将是

<?xml version="1.0" encoding="UTF-8"?>
empid=1
<ename>KING</ename>
<hiredate>17-11-1981</hiredate>
empid=2
<ename>BLAKE</ename>
<sub1>one</sub1>
<hiredate>1-5-1981</hiredate>
<sub2>two</sub2>

实际上,输出根本不是XML,并且没有必要使用XML声明。使用

declare namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
declare option output:omit-xml-declaration "yes";

摆脱声明。这应该适用于最新版本的BaseX。然后,输出将是

empid=1
<ename>KING</ename>
<hiredate>17-11-1981</hiredate>
empid=2
<ename>BLAKE</ename>
<sub1>one</sub1>
<hiredate>1-5-1981</hiredate>
<sub2>two</sub2>