mercredi 6 mai 2015

XSLT muenchian grouping with the help of key

I am trying to get to a solution and so far have got nothing. What I am trying to achieve is to transform

Input:
<?xml version="1.0" encoding="utf-8"?>
<Root>
    <Query>
        <ID>123123</ID>
        <NameOfTeam>Team1</NameOfTeam>
        <RaisingYear>2014</RaisingYear>
        <Brief>N/A</Brief>
        <TeamMembers>
          <Member>
            <Name>Person1</Name>
            <Role>Role1</Role>
          </Member>
          <Member>
            <Name>Person2</Name>
            <Role>Role2</Role>
          </Member>
            <Name>N/A</Name>
            <Role>
              Role4
            </Role>
          </Member>
        </TeamMembers>
        <TeamMembers2>
          <Member>
            <Name>Person3</Name>
            <Role>Role3</Role>
          </Member>
          <Member>
            <Name>Person4</Name>
            <Role>Role4</Role>
          </Member>
          <Member>
            <Name>Person5</Name>
            <Role>Role5</Role>
          </Member>
        </TeamMembers2>
        <Projects>
          <Project>NISAR</Project>
        </Projects>
        <Documents>
          <Document>
            <Language>en</Language>
            <LanguageName>English</LanguageName>
            <GeneralInfo>Useless project</GeneralInfo>
          </Document>
        </Documents>
      </Query>
      <Query>
        <ID>123124</ID>
        <NameOfTeam>Team2</NameOfTeam>
        <RaisingYear>2012</RaisingYear>
        <Brief>N/A</Brief>
        <TeamMembers>
          <Member>
            <Name>Person6</Name>
            <Role>Role1</Role>
          </Member>
          <Member>
            <Name>Person7</Name>
            <Role>Role2</Role>
          </Member>
            <Name>Person8</Name>
            <Role>Role3</Role>
          </Member>
        </TeamMembers>
        <TeamMembers2>
          <Member>
            <Name>Person3</Name>
            <Role>Role3</Role>
          </Member>
          <Member>
            <Name>Person4</Name>
            <Role>Role4</Role>
          </Member>
          <Member>
            <Name>Person5</Name>
            <Role>Role5</Role>
          </Member>
        </TeamMembers2>
        <Projects>
          <Project>MissionMars</Project>
        </Projects>
        <Documents>
          <Document>
            <Language>en</Language>
            <LanguageName>English</LanguageName>
            <GeneralInfo> </GeneralInfo>
          </Document>
          <Document>
            <Language>en</Language>
            <LanguageName>English</LanguageName>
            <GeneralInfo>It is a rubbish comment</GeneralInfo>
          </Document>
          <Document>
            <Language>fr</Language>
            <LanguageName>English</LanguageName>
            <GeneralInfo>It is another rubbish comment.</GeneralInfo>
          </Document>
        </Documents>
    </Query>
</Root>

to

Output:

<?xml version="1.0" encoding="utf-8"?>
<Root>
    <Query>
        <ID>123123</ID>
        <NameOfTeam>Team1</NameOfTeam>
        <RaisingYear>2014</RaisingYear>
        <Brief>N/A</Brief>
        <TeamMembers>
          <Member>
            <Name>Person1</Name>
            <Role>Role1</Role>
          </Member>
          <Member>
            <Name>Person2</Name>
            <Role>Role2</Role>
          </Member>
            <Name>N/A</Name>
            <Role>
              Role4
            </Role>
          </Member>
        </TeamMembers>
        <TeamMembers2>
          <Member>
            <Name>Person3</Name>
            <Role>Role3</Role>
          </Member>
          <Member>
            <Name>Person4</Name>
            <Role>Role4</Role>
          </Member>
          <Member>
            <Name>Person5</Name>
            <Role>Role5</Role>
          </Member>
        </TeamMembers2>
        <Projects>
          <Project>NISAR</Project>
        </Projects>
        <Documents>
          <Document>
            <Language>en</Language>
            <LanguageName>English</LanguageName>
            <GeneralInfo>Useless project</GeneralInfo>
          </Document>
        </Documents>
      </Query>
      <Query>
        <ID>123124</ID>
        <NameOfTeam>Team2</NameOfTeam>
        <RaisingYear>2012</RaisingYear>
        <Brief>N/A</Brief>
        <TeamMembers>
          <Member>
            <Name>Person6</Name>
            <Role>Role1</Role>
          </Member>
          <Member>
            <Name>Person7</Name>
            <Role>Role2</Role>
          </Member>
            <Name>Person8</Name>
            <Role>Role3</Role>
          </Member>
        </TeamMembers>
        <TeamMembers2>
          <Member>
            <Name>Person3</Name>
            <Role>Role3</Role>
          </Member>
          <Member>
            <Name>Person4</Name>
            <Role>Role4</Role>
          </Member>
          <Member>
            <Name>Person5</Name>
            <Role>Role5</Role>
          </Member>
        </TeamMembers2>
        <Projects>
          <Project>MissionMars</Project>
        </Projects>
        <Documents>
          <Document>
            <Language>en</Language>
            <LanguageName>English</LanguageName>
            <GeneralInfo>It is a rubbish comment</GeneralInfo>
          </Document>
          <Document>
            <Language>fr</Language>
            <LanguageName>English</LanguageName>
            <GeneralInfo>It is another rubbish comment.</GeneralInfo>
          </Document>
        </Documents>
    </Query>
</Root>

All document with same ID and Language information should be merged and if any of the details in document tag is empty than it should be replaced, only if available, by other document tag's information with same language tag.

The code that I am using for it is

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://ift.tt/tCZ8VR">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>

  <xsl:key name="QueryIDAndLangauge" match="Query" use="concat(ID, '+', Documents/Document/Language)"/>

  <xsl:key name="DocumentsAndLanguage" match="Language" use="Language"/>

  <xsl:key name="DocumentsAndLanguageValue" match="Language" use="concat(ID, '+', .)"/>

  <xsl:template match="node()|@*">
    <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="/*">
    <Root>
      <xsl:apply-templates select=
   "Query[generate-id()
          =
           generate-id(key('QueryIDAndLangauge',
                          concat(ID, '+', Documents/Document/Language)
                          )
                           [1]
                      )
           ]
   "/>
    </Root>
  </xsl:template>

  <xsl:template match="Document">
    <Document>
      <xsl:apply-templates select=
    "key('DocumentsAndLanguage', ../../ID)
        [generate-id()
        =
         generate-id(key('DocumentsAndLanguageValue',
                         concat(../../ID, '+', Langauge)
                         )
                          [1]
                     )
         ]
    "/>
    </Document>
  </xsl:template>
</xsl:stylesheet>

Thanks in Advance.

P.S.: Needless to mention, I am doing it in XSLT 1.0

Aucun commentaire:

Enregistrer un commentaire