使用 xquery for Exist-db 将节点从一个 xml 文件插入到另一个文件中

insert node from one xml file into another using xquery for Exist-db

我是 Exist-db 的 SQL 难民新手,我在弄清楚如何使用 xquery 获取 file1.xml 中节点的值时遇到了很多麻烦(a mysql dump) 并将其添加到 file2.xml(一个 TEI 文件)。我想将 file1 中的节点与 file2 中的 xml:id 值匹配。

我疯狂地四处搜索,试图了解 xquery 更新在 Exist-DB 中的工作原理,但似乎找不到包含更复杂示例的资源。

文件 1 如下所示:

<table_data name="places">
    <row>
        <field name="placeref">PLACEAFRICA</field>
                <field name="placename">Africa</field>
    </row>
    <row>
        <field name="placeref">PLACEILLINOIS</field>
        <field name="placename">Illinois</field>
    </row>
</table_data>

文件 2 看起来像这样(我想匹配文件 1 中名称属性 placeref 与文件 2 中 xml:id 的节点——值列表是不同的在两个文件中):

<listPlace>
                <place xml:id="PLACEAFRICA">
                        <bibl>OBRATDS</bibl>
                    </place>
                    <place xml:id="PLACEILLINOIS">
                        <bibl>OBRATDS</bibl>
                    </place>
</listPlace>

我想要发生的事情:

<listPlace>
                <place xml:id="PLACEAFRICA">
                        <bibl>OBRATDS</bibl>
                        <name>Africa</name>
                    </place>
                    <place xml:id="PLACEILLINOIS">
                        <bibl>OBRATDS</bibl>
                        <name>Illinois</name>
                    </place>
</listPlace>

发生了什么:

<listPlace>
                <place xml:id="PLACEAFRICA">
                        <bibl>OBRATDS</bibl>
                        <name>Africa</name>
                        <name>Illinois</name>
                    </place>
                    <place xml:id="PLACEILLINOIS">
                        <bibl>OBRATDS</bibl>
                        <name>Africa</name>
                        <name>Illinois</name>
                    </place>
</listPlace>

我使用的 xquery 代码:

let $file1 := doc('http://00.00.00.00/file1.xml')//row
let $file2 := doc('/db/madrid/xml/file2.xml')/* 
let $file2places := $file2//tei:place
let $file2placeref := $file2//tei:place/@xml:id
let $file1placeref := $file1//field[@name='placeref']//text() 
for  $file2placename in $file1//field[@name='placename']//text() 

let $placenamenodes :=  <name>{$file1placename}</name> 
where $file1placeref=$file2placeref 

return 
update insert $placenamenodes  into $file2places

任何关于我要去哪里(非常)错误的帮助或关于在哪里可以找到这种更新的资源(超出 Exist-db 资源)的想法将非常感激。对代码的混乱表示歉意——我尝试了很多不同的方法。

您的问题是 XQuery 初学者的常见问题。

$file2places 已选择所有地点。您只想插入到 xml:id 与您的 placeref 匹配的 $file2places 中。换句话说,您遗漏了目标的 WHERE 子句,从而将新名称标签插入到所有记录中。

尝试这样的事情:

(: Get source and target documents :)
let $rows := doc('http://00.00.00.00/file1.xml')//row
let $file2 := doc('/db/madrid/xml/file2.xml')/* 

(: Add place names by placerefs :)
for $row in $rows
  let $placeref := normalize-spaces($row/field[@name eq 'placeref'])
  let $placename := normalize-spaces($row/field[@name eq 'placename'])
  return update insert <name>{$placename}</name> 
    into $file2//place[@xml:id eq $placeref]

normalize-spaces 函数获取一个元素的所有文本值,将它们连接在一起,并删除前导和尾随 spaces 加上使单词 a 之间的全白 space单身 space。它比使用 //text().

更有效

主要是使用 [@xml:id eq $placeref] 过滤器限制添加了标签的地方。

希望对您有所帮助。