вставить узел из одного XML-файла в другой, используя xquery для Exist-db - PullRequest
0 голосов
/ 30 октября 2019

Я - беженец SQL, новичок в Exist-db, и у меня так много проблем с выяснением, как использовать xquery для получения значения узла в file1.xml (дамп mysql) и добавления его в file2.xml(файл TEI). Я хочу сопоставить узлы из file1 со значением xml:id в file2.

Я гуглил, как сумасшедший, пытаясь понять, как работают обновления 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 выглядит следующим образом (и я хочу сопоставить, где есть атрибут имени placeref в файле1 сузлы, где есть xml:id в File2 - список значений различен в обоих документах):

<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) будет очень признателен. Извиняюсь за запутанность кода - я пробовал так много разных подходов.

1 Ответ

2 голосов
/ 31 октября 2019

Ваша проблема типична для начинающих с XQuery.

$ file2places выбрал ВСЕ места. Вы хотите вставить только в $ file2places, где xml: id соответствует вашему placeref. Другими словами, вы пропустили предложение 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-space принимаетвсе текстовые значения элемента, объединяет их вместе и удаляет начальные и конечные пробелы, а также делает все пробелы между словами одним пробелом. Это более эффективно, чем использование //text().

Главное - ограничить количество мест, к которым добавлен тег, с помощью фильтра [@xml: id eq $ placeref].

Надеюсь, это поможет.

...