#xml #xslt #xquery
#xml #xslt #xquery
Вопрос:
Теперь у меня есть dita composite, например:
<root>
<topic>....</topic>
<topic>....</topic>
<topic>....</topic>
<topic>....</topic>
<topic>....</topic>
</root>
И мне просто нужно написать xquery, который в основном создаст ditamap для каждой темы, поэтому повторный ditamap должен выглядеть так:
<map>
<topicref>....</topicref>
<topicref>....</topicref>
<topicref>....</topicref>
<topicref>....</topicref>
<topicref>....</topicref>
</map>
Мой текущий Xquery не совсем правильно работает, он способен перехватывать каждую тему, но вместо создания одного ditamp он создает несколько ditamap, по одному для каждой темы:
$isFoSaved := for $b in $mapNode/*[local-name() = 'topic']
let
$topicWithPI := let $holder:=1
return (
<topicref href="1.xml#Begin" navtitle="Begin" scope="local" type="topic"/>
),
Могут ли эксперты помочь? Спасибо
Ответ №1:
Я вижу только, что вы встраиваете несколько выражений flwor.
Всякий раз, когда вы используете $x := let $y ...
или $x := for $y ...
запускаете новое выражение flwor, которое должно быть закрыто return
предложением. Следовательно, ваш обрезанный код является недопустимым / неполным: у вас есть два открытых выражения flwor, но только одно return
предложение.
Если вы попытаетесь сохранить его плоским, это будет намного проще.
Например:
<map>{
let $mapNode :=
<root>
<topic>....</topic>
<topic>....</topic>
<topic>....</topic>
<topic>....</topic>
<topic>....</topic>
</root>
for $b in $mapNode/*[local-name() = 'topic']
return
<topicref href="1.xml#Begin"
avtitle="Begin"
scope="local"
type="topic"/>
}</map>
этот запрос работает на try.zorba-xquery.com , но я не уверен, что это то, что вы ищете?
Комментарии:
1. Спасибо. Это действительно полезно. Могу ли я спросить вас подробнее, что, если у нас есть вложенные темы (т.Е. Тема внутри темы), можем ли мы зафиксировать это в xquery?
2. Конечно, это то, в чем XQuery / XPath лучше всего. Если вы просто используете $mapNode//*[local-name() = ‘topic’] (двойные шлаши), вы также получите ссылки на темы для всех дочерних элементов. Если вы хотите сохранить иерархию, это немного сложнее: см. Другой ответ.
Ответ №2:
Если вы хотите сохранить иерархию вложенных разделов, это немного сложнее. Я думаю, что для этого лучше всего использовать рекурсивную функцию:
declare function local:topicref($topics)
{
for $b in $topics
return
<topicref href="1.xml#Begin"
avtitle="Begin"
scope="local"
type="topic">{
local:topicref($b/*[local-name() = 'topic'])
}</topicref>
};
<map>{
let $mapNode :=
<root>
<topic><topic>....</topic></topic>
<topic>....</topic>
<topic>....</topic>
<topic>....</topic>
<topic>....</topic>
</root>
return
local:topicref(
$mapNode/*[local-name() = 'topic']
)
}</map>
Результат:
<?xml version="1.0" encoding="UTF-8"?>
<map>
<topicref href="1.xml#Begin" avtitle="Begin" scope="local" type="topic">
<topicref href="1.xml#Begin" avtitle="Begin" scope="local" type="topic"/>
</topicref>
<topicref href="1.xml#Begin" avtitle="Begin" scope="local" type="topic"/>
<topicref href="1.xml#Begin" avtitle="Begin" scope="local" type="topic"/>
<topicref href="1.xml#Begin" avtitle="Begin" scope="local" type="topic"/>
<topicref href="1.xml#Begin" avtitle="Begin" scope="local" type="topic"/>
</map>