2010-08-22 2 views
0

У меня есть XML, например:Получить предков какого-то узла с XQuery рекурсии

<types> 
    <type type="A"> 
    <type type="A.A"/> 
    <type type="A.B"> 
     <type type="A.B.A"/> 
    </type> 
    <type type="A.C"/> 
    </type> 
</types> 

Теперь у меня есть входной строки вроде: «A.B.A». Я хочу получить все предки и сам узел, который имеет эту строку, как значение атрибута «type». Это означает:

<types> 
    <type type="A"/> 
    <type type="A.B"/> 
    <type type="A.B.A"/> 
</types> 

(естественно имена типов здесь только примеры и не так просто, поэтому я не могу использовать функцию подстроки)
У меня есть два XML-схемы: TypesTree.xsd и Ancestros.xsd.
В обоих элементах «тип» и «типы».

Так, может быть, я могу использовать XPath с предками оси, где $ типы держит дерево типов:

let $seq := $types//type[@type=$typeName]/ancestor::* 
$seq := ($seq, $types//type[@type=$typeName]) 

Я новичок в XQuery, и я не уверен, что это будет работать, но дело не в том, что у меня нет оси «предков», реализованной в моем процессоре XQuery (!), и мне нужно явно писать код для этого процессора.

Поэтому я думаю написать некоторую рекурсивную функцию. Пусть «tre:» является префиксом TypeTree.xsd и «anc:» из Ancestors.xsd. Функция получит элемент tre: type и вернет последовательность элементов anc: type.

declare function BuildAncestors($type as element(tre:type), $typeName as xs:string) as element(anc:type)* 
{ 
    for $currentType in $type/tre:type (: for each nested type node :) 
    return 
    if ($currentType[@type=$typeName]) (: if current type node's attribute's values is what we search for :) 
    then ($currentType) (: return this node :) 
    else (: if this node's attribute's value isn't what we search, check it's children :) 
    let $retSeq := BuildAncestors($currentType, $typeName) (: get sequence of all ancestor's of this type till this node or null if $currentType has not searched node in it's descendants :) 
    if ($retSeq) (: if not null returned :) 
    then ($currentType, $retSeq) (: return new sequence built from this node and returned sequence :) 
    else() (: return null :) 
} 

Таким образом, ясно, что это не работа. Я даже не знаю, как я могу вернуть последовательность, добавить последовательности, вернуть null, проверить, возвращается ли null ...

Кто-нибудь знает, как я могу получить всех предков?

Благодарим за опережение.

ответ

0

Правильное обозначение оси ancestor, а не ancestors. Кроме того, использование оси ancestor-or-self было бы проще.

+0

Извините, мой настоящий код имеет своего предка :: и не предков ::. Просто наша сеть разработки не имеет доступа к inetrnet, поэтому я могу не копировать код. Но я нашел решение, я опубликую его. В любом случае, спасибо. – rodnower

0

Использование:

//type[@type=$pType]//ancestor-or-self::type[starts-with($pType, @type)] 

Если ваш процессор XQuery совместима со спецификацией W3C, он, вероятно, реализует ancestor:: and the ancestor-or-self:: осей.

Ошибка, которую вы получите, скорее всего, из-за опечатки - название оси ancestor, а не ancestors.

+0

Извините, мой настоящий код имеет своего предка :: и не предков ::. Просто наша сеть разработки не имеет доступа к inetrnet, поэтому я могу не копировать код. Но я нашел решение, я опубликую его. Спасибо вам любым способом. – rodnower

Смежные вопросы