根据XQuery中的元素和属性有条件地创建格式化字符串
我正在尝试将xml文档转换为特定的选项卡分隔平面文件结构。大多数元素都可以映射到单列,或者使用fn:string-join()简单地连接起来,但是我有一些元素的映射更复杂。示例元素如下所示:根据XQuery中的元素和属性有条件地创建格式化字符串,xquery,Xquery,我正在尝试将xml文档转换为特定的选项卡分隔平面文件结构。大多数元素都可以映射到单列,或者使用fn:string-join()简单地连接起来,但是我有一些元素的映射更复杂。示例元素如下所示: <record> <details> <passports> <passport country="">0018061/104</passport> <passport country="UK">03
<record>
<details>
<passports>
<passport country="">0018061/104</passport>
<passport country="UK">0354761445</passport>
<passport country="USA">M001806145</passport>
</passports>
</details>
<record>
0018061/104;(UK) 0354761445;(USA) M001806145
因此,如果@country
属性不是”
,则将其放入()
,否则将忽略它。元素值如下,每个元素之间用分隔代码>
以下是我迄今为止所做的工作:
for $record in //record
return concat($record/@uid/string(),
(: ... other columns ... :)
"	", <S>{for $r in //$record/details/passports/passport
return concat("(", $r/@country, ") ", $r, ";")}</S>/string()
," ")
理想情况下,我想知道这样做的正确方法,否则只需删除@country=”“
中的空括号就足够了。在外部concat
中使用if
子句(我在答案中添加了一些新行以提高可读性,您当然可以随意删除它们):
查询的新结果:
0018061/104; (UK) 0354761445; (USA) M001806145;
也可以使用隐式循环
/record/details/passports/passport/string-join(
(
"	",
if (@country != "")
then "(" || @country || ") "
else (),
.
), ""
)
或者显式循环结果,仍然有一个更干净的查询(通过用相应的concat(…)
调用替换串联运算符|
,您将保持XQuery 1.0的兼容性):
这两种情况都使用BaseX在标记之间插入的隐式换行符,或者您当然可以像以前一样添加它们。在外部concat
中使用if
子句(我在答案中添加了一些换行符以提高可读性,您当然可以根据需要删除它们):
查询的新结果:
0018061/104; (UK) 0354761445; (USA) M001806145;
也可以使用隐式循环
/record/details/passports/passport/string-join(
(
"	",
if (@country != "")
then "(" || @country || ") "
else (),
.
), ""
)
或者显式循环结果,仍然有一个更干净的查询(通过用相应的concat(…)
调用替换串联运算符|
,您将保持XQuery 1.0的兼容性):
这两种情况都使用BaseX在标记之间插入的隐式换行符,或者您当然可以像以前一样添加它们。请提供适合您发布的查询的示例输入(此处缺少包装记录和详细信息标记)。请提供适合您发布的查询的示例输入(此处缺少包装记录和详细信息标记)。请提供适合您发布的查询的示例输入(此处缺少包装记录和详细信息标记)。谢谢。我试过一个if语句,但我一定是在语法上做错了什么。这很好,谢谢。顺便问一下-有没有更好的方法避免使用循环或添加周围的?你使用的是什么查询处理器,它支持XQuery 3.0吗?BaseX 8.2-我相信它不支持XQuery 3,是的。我添加了一些建议以下是您如何获得灵感的结果。您需要
元素的原因是for
循环返回一个字符串序列,而不是单个字符串;您可以使用字符串连接($seq,“”)
(同时用已有的循环替换$seq
).注意,答案似乎表明“隐式循环”是XQuery 3.0的功能,不是。谢谢。我试过一个if语句,但我一定是在语法上做了一些错误。这很好,谢谢。顺便问一下-有没有更好的方法避免使用循环或添加周围的?你使用的是什么查询处理器,它支持XQuery 3.0吗?BaseX 8.2?我相信它支持BaseX supports XQuery 3,是的。我添加了一些建议,说明如何获得灵感的结果。之所以需要
元素,是因为for
循环返回一个字符串序列,而不是单个字符串;您可以使用字符串联接($seq,”)
(将$seq
替换为已有的循环)。注意,答案似乎表明“隐式循环”是XQuery 3.0的功能,不是。谢谢。我试过一个if语句,但我一定是在语法上做了一些错误。这很好,谢谢。顺便问一下-有没有更好的方法避免使用循环或添加周围的?你使用的是什么查询处理器,它支持XQuery 3.0吗?BaseX 8.2?我相信它支持BaseX supports XQuery 3,是的。我添加了一些建议,说明如何获得灵感的结果。之所以需要
元素,是因为for
循环返回一个字符串序列,而不是单个字符串;您可以使用字符串联接($seq,”)
(将$seq
替换为已有的循环)。注意,答案似乎表明“隐式循环”是XQuery 3.0功能,而不是。
for $record in /record/details/passports/passport
return (
"	" || (
if ($record/@country != "")
then "(" || $record/@country || ") "
else ()
) || $record
)