使用XQuery转换元素和内部的元素

时间:2018-06-20 15:03:40

标签: html xml xquery

我是XQuery的初学者,希望您可以轻松解决我的问题。我有以下XML示例:

<lg>
    <l n="1">Z nutz vnd heylsamer ler / verma⸗
    </l>
    <l n="2">nung vnd ervolgung der wyßheit / ver
    </l>
    <l n="3">nunfft vnd gter sytten : Ouch z ver⸗
    </l>
    <l n="4">achtung vnd straff der narheyt / blint⸗
    </l>
    <l n="5">heyt yrrsal vnd dorheit / aller stt / vnd
    </l>
    <l n="6">geschlecht der menschen : mit besun⸗
    </l>
    <l n="7">derem flyß ernst vnd arbeyt / gesamlet
    </l>
    <l n="8">z <ref target="narragonienLemmata.xml#basel">Basell</ref> : durch <ref target="narragonienLemmata.xml#brantSebastian">Sebastianum Brant</ref>.
    </l>
    <l n="9">in beyden rechten doctor.
    </l>
</lg>

我想做的是将每一行转换为HTML-div,同时,如果行中有内部,请将其转换为HTML-元素。现在,我的代码现在将ref放在块的末尾,因为我在两者之间使用了逗号:

for $line in //lg//l, $lem in $line//ref
return
    element div{$line, element a{$lem}}

我只是不知道建筑的工作原理……在此先感谢。

最好的问候, 多米尼卡

1 个答案:

答案 0 :(得分:4)

由于您的目标是执行转换,因此一种不错的处理方法是使用递归typeswitch函数。从概念上讲,它与XSLT类似,但更为明确。

declare function local:transform($n)
{
  typeswitch($n)
  case element(lg) return <div>{
    for $child in $n/*
    return local:transform($child)
    }</div>
  case element(ref) return <a>{ $n/(@*|node()) }</a>
  case element() return element { node-name($n)} {
    for $child in $n/(@*|node())
    return local:transform($child)
  }
  default return $n
};

typeswitch中,为要转换的每个元素或属性名称创建一个条目。在每个条目的return中,生成所需的元素,并在该元素内部指示要在其子元素上重复发生的变换。

在构建这些功能之一时,包括“身份”转换条目通常会很有帮助。这些将递归复制所有未明确定义的内容。这是typeswitch的身份部分:

...
case element() return element { node-name($n)} {
  for $child in $n/(@*|node())
  return local:transform($child)
}
default return $n
...

使用这种类型的功能,您可以更轻松地维护原始元素的结构,并专注于要进行的显式更改。