سؤال

I have a XML file containing Employees Name and the Job done by them. The structure of the XML file is -

<Employee>AAA@A#B#C#D</Employee>
<Employee>BBB@A#B#C#D</Employee>
<Employee>CCC@A#B#C#D</Employee>
<Employee>DDD@A#B#C#D</Employee>

There are thousands of records and I have to change structure to -

<Employee>
  <Name>AAA</Name>
  <Jobs>
   <Job>A</Job>
   <Job>B</Job>
   <Job>C</Job>
   <Job>D</Job>
  </Jobs>
</Employee>

How to get this done using XQuery in BaseX ?

هل كانت مفيدة؟

المحلول

3 XQuery functions, substring-before, substring-after and tokenize are used to get the required output.

substring-before is used to get the Name.

Similarly, the substring-after is used to get the Job portion.

Then the tokenize function, is used to split the Jobs.

let $data :=
  <E>
    <Employee>AAA@A#B#C#D</Employee>
    <Employee>BBB@A#B#C#D</Employee>
    <Employee>CCC@A#B#C#D</Employee>
    <Employee>DDD@A#B#C#D</Employee>
  </E>


for $x in $data/Employee
return 

<Employee>
   {<Name>{substring-before($x,"@")}</Name>}
   {<Jobs>{
   for $tag in tokenize(substring-after($x,"@"),'#')
   return 
     <Job>{$tag}</Job>
   }</Jobs>
}</Employee>

HTH...

نصائح أخرى

Tokenizing the string is probably easier and faster. tokenize($string, $pattern) splits $string using the regular expression $pattern, head($seq) returns the first value of a sequence and tail($seq) all but the first. You could also use positional predicates of course, but these functions are easier to read.

for $employee in //Employee
let $tokens := tokenize($employee, '[@#]')
return element Employee {
  element Name { head($tokens) },
  element Jobs {
    for $job in tail($tokens)
    return element Job { $job }
  }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top