非常复杂的XQuery转换

时间:2013-03-21 15:00:23

标签: xquery

我有一个非常复杂的XQuery要写(至少按我的标准)。

这是我的输入xml:

<testRequest>
    <request1>
       <Line>1</Line>
       <action>addtoName</action>
    </request1>
    <request2>
        <Line>2</Line>
        <action>addtoSpace</action>
    </request2>
    <request3>
         <Line>3<Line>
         <action>addtospace</action>
    </request3>
</testRequest>

在我的输出xml中,操作应作为属性附加到“request1”元素。因此,基于request1元素下的action元素,request1元素的属性应该是以下之一:

if action = IgnoreCase(addtoName), the request1 element should be <request1 action=insertingname>
if action =  IgnoreCase(addtoSpace), the request1 element should be <request1 action=updatingspace>

不仅如此,我还需要根据元素下面的动作值为元素添加属性。      所以,我必须遍历一个元素下的每个元素,看看是否有任何元素等于“addtospace”,如果是,那么我需要得到元素的相应值并构成元素的属性。从上面的xml中,我的元素属性应为

<testRequest lineFiller="Line Like 2_* AND Line Like 3_*>, where 2 and 3 are the respective line numbers.

如果没有element = addtoSpace的元素,那么元素的属性应该“改变”。

因此,总而言之,我的转换后的xml应如下所示:

<testRequest lineFiller="Line Like 2_* AND Line Like 3_*>
    <request1 action=insertingname>
       <Line>1</Line>
       <action>addtoName</action>
    </request1>
    <request2 action=updatingspace>
        <Line>2</Line>
        <action>addtoSpace</action>
    </request2>
    <request3 action=updatingspace>
         <Line>3<Line>
         <action>addtospace</action>
    </request3>
</testRequest>

非常感谢任何有助于完成这项重大任务的帮助。

感谢!!!

1 个答案:

答案 0 :(得分:1)

您应该定义函数以生成需要添加到元素的属性。

要添加到“request”元素,这应该有效:

declare function local:getaction($x) {
  if (lower-case($x/action) = "addtoname") then attribute action {"insertingspace"} else
  if (lower-case($x/action) = "addtospace") then attribute action {"updatingspace"} else
  ()
};

可以类似地创建linefiller属性:

declare function local:getfiller($x) {
  attribute lineFiller {
      if ($x/*[lower-case(action) = "addtospace"]) then
          string-join(
          for $r in $x/*[lower-case(action) = "addtospace"]
            return concat("Line Like ",$r/Line,"_*")
          , " AND ")
      else "change"
      }
};

然后将它们放在一起,为原始文档提供一个简单的循环,在需要的地方添加属性:

let $doc:=<<your original document>>

return
<testRequest>
{ local:getfiller($doc) }
{ for $r in $doc/* return 
   element { name($r) } { 
    local:getaction($r),
    $r/* 
   }
}
</testRequest>

编辑:增强的getfiller功能,如果没有动作则返回“更改”