Search code examples
xpathxquerymarklogicmarklogic-8

How to denormalize xml file?


I have 3 XML file that belongs to same family as mentioned below:

Aplha_a.xml

<root>
  <date>24-july-2017</date>
  <ID>001</ID>
  <data>a</data>
  <reg_date>24-july-2017</reg_date>
</root>

Aplha_b.xml

<root>
  <date>24-july-2017</date>
  <ID>001</ID>
  <data>b</data>
  <reg_date>24-july-2017</reg_date>
</root>

Aplha_c.xml

<root>
  <date>24-july-2017</date>
  <ID>001</ID>
  <data>c</data>
  <reg_date>24-july-2017</reg_date>
</root>

The 3 different XML files are now organized into single XML file as mentioned below:

<Alpha_family>
    <root>
      <date>24-july-2017</date>
      <ID>001</ID>
      <data>a</data>
      <reg_date>24-july-2017</reg_date>
    </root>
    <root>
      <date>24-july-2017</date>
      <ID>001</ID>
      <data>b</data>
      <reg_date>24-july-2017</reg_date>
    </root>
    <root>
      <date>24-july-2017</date>
      <ID>001</ID>
      <data>c</data>
      <reg_date>24-july-2017</reg_date>
    </root>
</Alpha_family>

I need to de-normalize the 3 XML file into a single XML family element by returning only distinct-nodes.

<Alpha_family>
  <date>24-july-2017</date>
  <ID>001</ID>
  <data>a b c</data>
  <reg_date>24-july-2017</reg_date>
</Alpha_family>

Can anyone help on this.

Thanks in advance.


Solution

  • So it isn't quite clear how you want your newly "denormalized" nodes to be composed, but from the example output given I am going to assume you want to join all distinct values and separate them by a whitespace.

    The following should do the job:

    for $family in /Alpha_family
    return element { $family/local-name() } {
      for $e in distinct-values($family/*/*/local-name())
      return element { $e } { distinct-values($family/*/*[local-name() = $e])}
    }
    

    It first gets all distinct element names and then joins the distinct values of these elements.