Aspir3l
Aspir3l

Reputation: 7

Merging two XML files using XSL transformation

I've been trying to merge two xml files into another XML with the output of both combined using XSL but haven't been able to. The xml's are quite large, so I'll only include a small portion. I'm really lost on this task. I can transform a single XML file but merge two is something I have never done and can't find much information on it related to my specific case.

XML 1:

<Games>
    <Game>
        <Date>01/05/2019</Date>
        <PlayerID>454asdsad</PlayerID>
        <Place>1</Place>
        <GameID>CpsQf125AFy</GameID>
        <Payment currency="gbp">50</Payment>
    </Game>

    .....repeats the above many times with different values.
</Games>

XML 2:

<Players>
    <Player>
        <Title>Mr</Title>
        <Lastname>Doe</Lastname>
        <Firstname>John</Firstname>
        <IDnumber>454asdsad</IDnumber>
        <Address>Streetname</Address>
    </Player>

   .....repeats the above many times with different values.
</Players>

Expected result:

<Games>
      <Place>
        <Date>
          <Game>
            <Title>Mr</prefix>
            <Lastname>Doe</Lastname>
            <Firstname>John</Firstname>
            <IDnumber>454asdsad</IDnumber>
            <Address>Streetname</Address>
            <Date>01/05/2019</Date>
            <PlayerID>454asdsad</Player>
            <Place>1</Place>
            <GameID>CpsQf125AFy</GameID>
            <Payment currency="gbp">50</Payment>
          </Game>
       </Date>

       <Date> ...if there are more dates is the same place as above.
          <Game>
               ....information
          </Game>
       </Date>

     </Place>

     <Place> ...another place
       <Date>
         <Game>
            ...all the information like above, with the appropriate next values from both XML's.
         </Game>
       </Date>

       <Date> ...if there are more dates is the same place as above.
         <Game>
              ....information
         </Game>
       <Date>
     </Place>

     ...repeats same thing and format until the end.
 </Games>

Upvotes: 0

Views: 94

Answers (2)

Michael Kay
Michael Kay

Reputation: 163585

There are two parts to this:

  • grouping, first on place and then on date

  • joining, fetching in data from the second file selected by personID.

The grouping is basically

<xsl:for-each-group select="Game" group-by="Place">
  <Place>
    <xsl:for-each-group select="current-group()" group-by="Date">
      <Date>
        <xsl:for-each select="current-group()">
          <Game>
             XXXXX
             <xsl:copy-of select="*"/>

And at XXXXX you need to do the join, which is basically

<xsl:copy-of select="key('player-id', PlayerID, $players-xml')/*"/>

where $players-xml is the Players.xml document, and the key is defined as

<xsl:key name="player-id" match="Player" use="IDNumber"/>

Upvotes: 1

Martin Honnen
Martin Honnen

Reputation: 167716

If you know about for-each-group, then you should have no problems to pull in elements from both documents with e.g. <xsl:for-each-group select="/Games/Game, doc('file2.xml')/Players/Player" group-by="PlayerID, IDnumber">, the grouping key will by PlayerID where that element exists and IDnumber where that elements exists, as long as there are no elements having both child elements that approach should be safe or could be corrected to group-by="(PlayerID, IDnumber)[1]" to select one key if not.

And if there is also the need to group by Place you can nest another for-each-group select="current-group()" group-by="Place" or use a composite key.

Upvotes: 1

Related Questions