【发布时间】:2019-12-04 07:26:08
【问题描述】:
这是我的 xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<QQ:Envelope xmlns:QQ="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header>
<RR:ABCInfo xmlns:RR="http://abc.test.de/abc/SOAP-Header/1.0">
<RR:Version>2.2.2.2</RR:Version>
<RR:BuildRevision>3333</RR:BuildRevision>
<RR:BuildTimestamp>2019-01-01T00:00:00.000+02:00</RR:BuildTimestamp>
<RR:Start>2019-01-01T10:10:10.101+02:00</RR:Start>
<RR:End>2019-01-01T11:11:11.111+02:00</RR:End>
<RR:Something>2.222 sek.</RR:Something>
<RR:Anything/>
</RR:ABCInfo>
<work:WorkContext xmlns:work="http://test.com/">1234567890abcdefghijklmnopqrstuvwxyz</work:WorkContext>
</SOAP-ENV:Header>
<QQ:Body>
<TT:testA xmlns:TT="http://abc.test.de/XYZ/2.0.1" xmlns:RR="http://abc.test.de/abc/abcdefgh/1.0">
<TT:testB>
<TT:testC>
<TT:testD>
<TT:testE id="1234567" quellID="09876543">
<TT:data>urn:de:abc:test:whatever</TT:data>
<TT:changeDate>2019-02-02T02:02:02.020+02:00</TT:changeDate>
<TT:part1 listURI="urn:de:abc:codeliste:555" listVersionID="V12">
<code>555_777</code>
<name>Fischers Fritze</name>
</TT:part1>
<TT:piece2>Frische Fische fischen</TT:piece2>
<TT:begin>
<TT:date>20191231</TT:date>
</TT:begin>
</TT:testE>
</TT:testD>
</TT:testC>
</TT:testB>
</TT:testA>
</QQ:Body>
</QQ:Envelope>
我有一个 XQuery,我必须在其中返回 XML。返回的 XML 中的第一个元素是“结果”。返回的 XML 中的其他元素应该是动态创建的。
我从外部获得了 2 个序列,尽管我在以下示例中制作了 2 个修复序列来测试它。 在序列号 1 中,我得到了其他元素的名称。 在序列号 2 中,我得到序列号 1 中元素名称的相关路径。
我打开 XML 文件并读取路径(可能有多个元素,但在我的示例中只有一个。 然后我想循环处理这个结果并返回动态元素。 如果我使用固定值(以下代码中的变量 $c)访问路径,我会得到正确的值,但是我必须知道序列 1 中的元素和序列 2 中的路径。 如果我连接路径,那么我会从所有元素中获取值。
这是我的 XQuery 代码:
declare namespace TT="http://abc.test.de/XYZ/2.0.1";
declare namespace QQ="http://schemas.xmlsoap.org/soap/envelope/";
declare function local:getValue($path) as xs:string {
if (fn:exists($path)) then
(
data($path)
) else (
""
)
};
let $a := ('part1', 'piece2', 'beginDate')
let $b := ('TT:part1/name','TT:piece2', 'TT:begin/TT:date')
for $x in doc("Test.XML")/QQ:Envelope/QQ:Body/TT:testA/TT:testB/TT:testC/TT:testD/TT:testE
return <result>
{
for $item at $ind in $a
let $c := local:getValue($x/TT:part1/name)
let $d := local:getValue($x || concat("/", $b[$ind]))
return element { $item } {$c, " --- ", $d}
}
</result>
是否可以动态访问路径?
提前谢谢你。
【问题讨论】:
-
您使用哪个 XQuery 处理器?有些具有动态评估功能,例如 BaseX docs.basex.org/wiki/XQuery_Module#xquery:eval
-
从技术上讲,您可以从 XQuery 3.1 进行动态 XPath 评估,方法是构造一个包含 XPath 表达式的 XSLT 样式表,并使用 fn:transform() 调用它。但是,这种工作的机会与发现您的处理器有自己的、更直接的方法来完成任务的机会大致相同。挑战通常是如何为 XPath 评估传递上下文(例如命名空间、变量等)
-
在我的测试中,我使用的是 BaseX。
-
但在生产中,我会将其嵌入到 Oracle 12c 数据库中的 PL/SQL 过程中(因此不可能使用 XQuery 3.1)。也许我们会在几周内将数据库更改为 Oracle 18,但我认为 Oracle 18 只能使用 Xquery 3.0。
-
由于该特性超出了标准化的 XQuery 语言特性,而且在数据库世界中,至少据我所知,主要是关系数据库系统中对 XML 列类型的大多数 XQuery 支持通常不无论如何努力实现完整的 W3C 标准,我认为您需要研究您的特定数据库系统为 XQuery 动态评估提供的功能,如果那是您真正需要的。我不太确定你是否真的需要在字符串中使用路径表达式。
标签: xquery