XML 中的 XQuery 简单递归查询子级到顶级父级
XQuery Simple Recursive Query child to top parent in XML
Input xml
<req>
<family>
<person>
<id>id1</id>
<name>name1</name>
<mother>mother1</mother>
<age>age1</age>
</person>
<person>
<id>id2</id>
<name>name2</name>
<mother>mother2</mother>
<age>age2</age>
</person>
<person>
<id>id4</id>
<name>mother3</name>
<mother>mother4</mother>
</person>
<person>
<id>id3</id>
<name>mother2</name>
<mother>mother3</mother>
<age>age3</age>
</person>
</family>
</req>
Could you please help me how to get the top parrent 'person' with existing element 'age' for every 'req/family/person'?
My follow xquery
declare function local:recons($family as element(*), $person as element(*))
as element(*) {
let $parrent := for $p in $family/person
where $p/name=$person/mother
return local:recons($family,$p)
return
<person>
{$person/*}
<parrent>{$parrent}</parrent>
</person>
};
declare function xf:MyTest($inputXML as element(*))
as element(*) {
<res>
<family>
{
for $person in $inputXML/family/person
return local:recons($inputXML/family,$person)
}
</family>
</res>
};
declare variable $inputXML as element(*) external;
xf:MyTest($inputXML)
Expected result
<res>
<family>
...
<person>
<id>id2</id>
<name>name2</name>
<mother>mother2</mother>
<age>age2</age>
<parrent>
<person>
<id>id3</id>
<name>mother2</name>
<mother>mother3</mother>
<age>age3</age>
<parrent/>
</person>
</parrent>
</person>
...
</family>
</res>
Actual result
<res>
<family>
...
<person>
<id>id2</id>
<name>name2</name>
<mother>mother2</mother>
<age>age2</age>
<parrent>
<person>
<id>id3</id>
<name>mother2</name>
<mother>mother3</mother>
<age>age3</age>
<parrent>
<person>
<id>id4</id>
<name>mother3</name>
<mother>mother4</mother>
<parrent/>
</person>
</parrent>
</person>
</parrent>
</person>
...
</family>
</res>
I tried use ancestor and xpath like '$parrent//person[fn:exists(age)]', unsuccessful.
I tried use ancestor and xpath like '$parrent//person[fn:exists(age)]', unsuccessful.
调整 where
子句你的 local:recons()
以确保你只选择 $parrent
(该元素和变量不应该拼写为 parent 吗?)如果它有 age
并且它的 name
匹配 $person/mother
您可以使用谓词过滤器轻松做到这一点:
where $p[age]/name = $person/mother
应用于函数:
declare function local:recons($family as element(*), $person as element(*))
as element(*) {
let $parrent := for $p in $family/person
where $p[age]/name = $person/mother
return local:recons($family,$p)
return
<person>
{$person/*}
<parrent>{$parrent}</parrent>
</person>
};
Input xml
<req>
<family>
<person>
<id>id1</id>
<name>name1</name>
<mother>mother1</mother>
<age>age1</age>
</person>
<person>
<id>id2</id>
<name>name2</name>
<mother>mother2</mother>
<age>age2</age>
</person>
<person>
<id>id4</id>
<name>mother3</name>
<mother>mother4</mother>
</person>
<person>
<id>id3</id>
<name>mother2</name>
<mother>mother3</mother>
<age>age3</age>
</person>
</family>
</req>
Could you please help me how to get the top parrent 'person' with existing element 'age' for every 'req/family/person'?
My follow xquery
declare function local:recons($family as element(*), $person as element(*))
as element(*) {
let $parrent := for $p in $family/person
where $p/name=$person/mother
return local:recons($family,$p)
return
<person>
{$person/*}
<parrent>{$parrent}</parrent>
</person>
};
declare function xf:MyTest($inputXML as element(*))
as element(*) {
<res>
<family>
{
for $person in $inputXML/family/person
return local:recons($inputXML/family,$person)
}
</family>
</res>
};
declare variable $inputXML as element(*) external;
xf:MyTest($inputXML)
Expected result
<res>
<family>
...
<person>
<id>id2</id>
<name>name2</name>
<mother>mother2</mother>
<age>age2</age>
<parrent>
<person>
<id>id3</id>
<name>mother2</name>
<mother>mother3</mother>
<age>age3</age>
<parrent/>
</person>
</parrent>
</person>
...
</family>
</res>
Actual result
<res>
<family>
...
<person>
<id>id2</id>
<name>name2</name>
<mother>mother2</mother>
<age>age2</age>
<parrent>
<person>
<id>id3</id>
<name>mother2</name>
<mother>mother3</mother>
<age>age3</age>
<parrent>
<person>
<id>id4</id>
<name>mother3</name>
<mother>mother4</mother>
<parrent/>
</person>
</parrent>
</person>
</parrent>
</person>
...
</family>
</res>
I tried use ancestor and xpath like '$parrent//person[fn:exists(age)]', unsuccessful. I tried use ancestor and xpath like '$parrent//person[fn:exists(age)]', unsuccessful.
调整 where
子句你的 local:recons()
以确保你只选择 $parrent
(该元素和变量不应该拼写为 parent 吗?)如果它有 age
并且它的 name
匹配 $person/mother
您可以使用谓词过滤器轻松做到这一点:
where $p[age]/name = $person/mother
应用于函数:
declare function local:recons($family as element(*), $person as element(*))
as element(*) {
let $parrent := for $p in $family/person
where $p[age]/name = $person/mother
return local:recons($family,$p)
return
<person>
{$person/*}
<parrent>{$parrent}</parrent>
</person>
};