JavaPassion
JavaPassion

Reputation: 95

Splitting XML using XSLT based on same child Nodes and retain Header part with additional information

Requirement: Split the Body of XML with same nodes and in the header tag retain the original tags and append unique Id from the child nodes of the body part of the xml.

e.g:

<Document>
<Header>
    <Time>2011-04-22T10:57:00.000-04:00</Time>
</Header>
<Child>
    <submit>
        <application>
            ...
        </application>
    </submit>
    <IssuingAgency>
        ...
        <AgentIdentification>
            <IdentificationID>103701978</IdentificationID>
        </AgentIdentification>
        <AgentSequenceID>01</AgentSequenceID>
        <AgentSatus>
            <StatusText>ABC</StatusText>
            <StatusDescriptionText>Initial</StatusDescriptionText>
        </AgentSatus>
        ...
        ...
        ...
    </IssuingAgency>
</Child>
<Child>
    <submit>
        <application>
            ...
        </application>
    </submit>
    <IssuingAgency>
        <AgentIdentification>
            <IdentificationID>103701978</IdentificationID>
        </AgentIdentification>
        <AgentSequenceID>01</AgentSequenceID>
        <AgentSatus>
            <StatusText>R</StatusText>
            <StatusDescriptionText>Renewal</StatusDescriptionText>
        </AgentSatus>
        ...
        ...
        ...
    </IssuingAgency>
</Child>
<Child>
    <submit>
        <application>
            ...
        </application>
    </submit>
    <IssuingAgency>
            ...
        <AgentIdentification>
            <IdentificationID>103701978</IdentificationID>
        </AgentIdentification>
        <AgentSequenceID>01</AgentSequenceID>
        <AgentSatus>
            <StatusText>R</StatusText>
            <StatusDescriptionText>Renewal</StatusDescriptionText>
        </AgentSatus>
            ...
            ...
            ...
    </IssuingAgency>
</Child></Document>

Now I need the output as: output1.xml

<Document>
<Header>
    <Time>2011-04-22T10:57:00.000-04:00</Time>
    <UniqueId>103701978-01-ABC</UniqueId> 
</Header>
<Child>
    ...
    ... ALL Information should not be removed, they have to be retained 
    ...
    <IssuingAgency>
        <AgentIdentification>
            <IdentificationID>103701978</IdentificationID>
        </AgentIdentification>
        <AgentSequenceID>01</AgentSequenceID>
        <AgentSatus>
            <StatusText>ABC</StatusText>
            <StatusDescriptionText>Initial</StatusDescriptionText>
        </AgentSatus>
    </IssuingAgency>
    ...
    ...ALL Information should not be removed, they have to be retained
    ...

</Child></Document>

Now here if it is observed the Header portion is being appended with Uinque Id which is a combination of Child/IssuingAgency/AgentIdentification/IdentificationID - Child/IssuingAgency/AgentSequenceID - Child/IssuingAgency/AgentSatus/StatusText

Likewise I would need three different XML files. The number of generated files are dynamic in nature there can be 10 Childs so the output may be 10 different files but with the header information being added with the unique id.

I tried generating different files with the xslt but the problem is I am unable to add the Header information along with them, I need help from you guys to have this fixed. Would really appreciate if it is addressed quickly. Have been trying for the past 1 week with no luck :(

Upvotes: 0

Views: 434

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167696

Assuming XSLT 2.0, the following uses xsl:result-document and a tunnel parameter:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
exclude-result-prefixes="xs"
version="2.0">

<xsl:template match="/">
  <xsl:apply-templates select="Document/Child" mode="new-doc"/>
</xsl:template>

<xsl:template match="Child" mode="new-doc">
  <xsl:result-document href="output{position()}.xml">
    <xsl:apply-templates select="ancestor::*">
      <xsl:with-param name="current-child" select="current()" tunnel="yes"/>
    </xsl:apply-templates>
  </xsl:result-document>
</xsl:template>

<xsl:template match="*">
  <xsl:copy>
    <xsl:copy-of select="@*"/>
    <xsl:apply-templates/>
  </xsl:copy>
</xsl:template>

<xsl:template match="Child">
  <xsl:param name="current-child" tunnel="yes"/>
  <xsl:if test=". is $current-child">
      <xsl:copy-of select="."/>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

Upvotes: 1

Related Questions