Reputation: 123
I'm having an xml as below:
<?xml version="1.0" encoding="utf-8"?><Master>
<Account ID="38058226">
<Property ID="66591454">
<Profile ID="111234">\Acct_38058226\Prop_66591454\Prof_111234.xml</Profile>
</Property>
</Account>
<Account ID="38058226">
<Property ID="66591454">
<Profile ID="22222222222">\Acct_38058226\Prop_66591454\Prof_22222222222.xml</Profile>
</Property>
</Account>
<Account ID="38058226">
<Property ID="66591455">
<Profile ID="000000">\Acct_38058226\Prop_66591454\Prof_000000.xml</Profile>
</Property>
</Account>
<Account ID="38058227">
<Property ID="66591454">
<Profile ID="000000">\Acct_38058226\Prop_66591454\Prof_000000.xml</Profile>
</Property>
</Account>
</Master>
The output I'm looking for is:
<Master>
<Account ID="38058226">
<Property ID="66591454">
<Profile ID="111234">\Acct_38058226\Prop_66591454\Prof_111234.xml</Profile>
<Profile ID="22222222222">\Acct_38058226\Prop_66591454\Prof_22222222222.xml</Profile>
</Property>
<Property ID="66591455">
<Profile ID="000000">\Acct_38058226\Prop_66591454\Prof_000000.xml</Profile>
</Property>
</Account>
<Account ID="38058227">
<Property ID="66591454">
<Profile ID="000000">\Acct_38058226\Prop_66591454\Prof_000000.xml</Profile>
</Property>
</Account>
</Master>
I'm using XSLT 1.0. The xml keeps on expanding every night. I'm very new to xml/xslt. I spent hours in my hand in studying it but the delivery is very near and hence seeking the help. The hint which I got is that I might have to use the Muenchian Grouping, forming the keys and grouping. I'm still learning and not able to create the logic for myself yet. Thanks in advance!!
Upvotes: 1
Views: 56
Reputation: 3738
Here's one way to do it.
When this XSLT:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key
name="kAccounts"
match="Account"
use="@ID"/>
<xsl:key
name="kPropertiesByAccount"
match="Property"
use="parent::Account/@ID"/>
<xsl:key
name="kPropertiesByIdAndAccount"
match="Property"
use="concat(@ID, '+', parent::Account/@ID)"/>
<xsl:key
name="kProfileByPropertyAndAccount"
match="Profile"
use="concat(parent::Property/@ID, '+', ancestor::Account/@ID)"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/*">
<Master>
<xsl:apply-templates
select="Account[
generate-id() = generate-id(key('kAccounts', @ID)[1])
]"/>
</Master>
</xsl:template>
<xsl:template match="Account">
<xsl:copy>
<xsl:apply-templates
select="@*|key(
'kPropertiesByAccount', @ID)[
generate-id() =
generate-id(
key('kPropertiesByIdAndAccount',
concat(@ID, '+', parent::Account/@ID))[1])
]"/>
</xsl:copy>
</xsl:template>
<xsl:template match="Property">
<xsl:copy>
<xsl:apply-templates
select="@*|key(
'kProfileByPropertyAndAccount',
concat(@ID, '+', parent::Account/@ID))"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
...is run against the provided XML:
<?xml version="1.0" encoding="UTF-8"?>
<Master>
<Account ID="38058226">
<Property ID="66591454">
<Profile ID="111234">\Acct_38058226\Prop_66591454\Prof_111234.xml</Profile>
</Property>
</Account>
<Account ID="38058226">
<Property ID="66591454">
<Profile ID="22222222222">\Acct_38058226\Prop_66591454\Prof_22222222222.xml</Profile>
</Property>
</Account>
<Account ID="38058226">
<Property ID="66591455">
<Profile ID="000000">\Acct_38058226\Prop_66591454\Prof_000000.xml</Profile>
</Property>
</Account>
<Account ID="38058227">
<Property ID="66591454">
<Profile ID="000000">\Acct_38058226\Prop_66591454\Prof_000000.xml</Profile>
</Property>
</Account>
</Master>
...the wanted result is produced:
<Master>
<Account ID="38058226">
<Property ID="66591454">
<Profile ID="111234">\Acct_38058226\Prop_66591454\Prof_111234.xml</Profile>
<Profile ID="22222222222">\Acct_38058226\Prop_66591454\Prof_22222222222.xml</Profile>
</Property>
<Property ID="66591455">
<Profile ID="000000">\Acct_38058226\Prop_66591454\Prof_000000.xml</Profile>
</Property>
</Account>
<Account ID="38058227">
<Property ID="66591454">
<Profile ID="000000">\Acct_38058226\Prop_66591454\Prof_000000.xml</Profile>
</Property>
</Account>
</Master>
Note that Muenchian Grouping (as evidenced by the use of <xsl:key>
and generate-id()
) is, indeed, the way to go.
Upvotes: 2