1
votes

I am trying to create an XSLT to transform an XML document and having trouble with grouping. I have no problems pulling out information for a single object, but multiple objects is where I am failing. I have read through and attempted many of the pre-existing grouping questions/solutions, but I am not super savy when it comes to XML.

XML to be transformed:

<?xml version="1.0" encoding="UTF-8"?>
<File xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Building>
<BuildingName>Abbotsford 607 Spruce</BuildingName>
<BuildingCode>80255</BuildingCode>
<BuildingAddress>607 East Spruce St</BuildingAddress>
<BuildingCity>Abbotsford</BuildingCity>
<BuildingState>Wisconsin</BuildingState>
<BuildingStateCode>WI</BuildingStateCode>
<BuildingCountry>United States</BuildingCountry>
<ZipCode>54405-9659</ZipCode>
<Room>
<ID>32182</ID>
<Name>001B</Name>
<FloorName>01</FloorName>
</Room>
</Building>
<Building>
<BuildingName>Allouez 2001 Webster</BuildingName>
<BuildingCode>80006</BuildingCode>
<BuildingAddress>2001 S Webster Avenue</BuildingAddress>
<BuildingCity>Green Bay</BuildingCity>
<BuildingState>Wisconsin</BuildingState>
<BuildingStateCode>WI</BuildingStateCode>
<BuildingCountry>United States</BuildingCountry>
<ZipCode>54301</ZipCode>
<Room>
<ID>22320</ID>
<Name>001B</Name>
<FloorName>01</FloorName>
</Room>
<Room>
<ID>22319</ID>
<Name>002B</Name>
<FloorName>02</FloorName>
</Room>
</Building>
</File>

Expected results:

<?xml version="1.0" encoding="UTF-8"?>
<FMRequest>
<Transaction Type="UpdateAdd">
<BusinessObjectList>
    <BusinessObject Name="LocationGroup.EmployeeSite">
        <FieldList>
            <Field Name="ABC_PropertyManagementName" identifier="true" UpdateOverride="None">Abbotsford 607 Spruce</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Purpose">Work</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Address">607 East Spruce St</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.City">Abbotsford</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.State">WI</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Zip">54405-9659</Field> 
        </FieldList>
    <RelatedBusinessObjectList>
        <BusinessObject Name="LocationGroup.ABC_Floor">
            <FieldList>
                <Field Name="ABC_Building" identifier="true" UpdateOverride="None">Abbotsford 607 Spruce</Field> 
                <Field Name="ABC_Floor">01</Field>
            </FieldList>
        </BusinessObject>
        <BusinessObject Name="LocationGroup.ABC_Room">
            <FieldList>
                <Field Name="ABC_RoomID" identifier="true" UpdateOverride="None">32182</Field>
                <Field Name="ABC_Building">Abbotsford 607 Spruce</Field> 
                <Field Name="ABC_Floor">01</Field>
                <Field Name="ABC_Room">001B</Field>
            </FieldList>
        </BusinessObject>
    </RelatedBusinessObjectList>
    </BusinessObject>
    <BusinessObject Name="LocationGroup.EmployeeSite">
        <FieldList>
            <Field Name="ABC_PropertyManagementName" identifier="true" UpdateOverride="None">Allouez 2001 Webster</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Purpose">Work</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Address">2001 S Webster Avenue</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.City">Green Bay</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.State">WI</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Zip">54301</Field> 
        </FieldList>
    <RelatedBusinessObjectList>
        <BusinessObject Name="LocationGroup.ABC_Floor">
            <FieldList>
                <Field Name="ABC_Building" identifier="true" UpdateOverride="None">Allouez 2001 Webster</Field> 
                <Field Name="ABC_Floor">01</Field>
            </FieldList>
        </BusinessObject>
        <BusinessObject Name="LocationGroup.ABC_Floor">
            <FieldList>
                <Field Name="ABC_Building" identifier="true" UpdateOverride="None">Allouez 2001 Webster</Field> 
                <Field Name="ABC_Floor">02</Field>
            </FieldList>
        </BusinessObject>
        <BusinessObject Name="LocationGroup.ABC_Room">
            <FieldList>
                <Field Name="ABC_RoomID" identifier="true" UpdateOverride="None">22320</Field>
                <Field Name="ABC_Building">Allouez 2001 Webster</Field> 
                <Field Name="ABC_Floor">01</Field>
                <Field Name="ABC_Room">001B</Field>
            </FieldList>
        </BusinessObject>
        <BusinessObject Name="LocationGroup.ABC_Room">
            <FieldList>
                <Field Name="ABC_RoomID" identifier="true" UpdateOverride="None">22319</Field>
                <Field Name="ABC_Building">Allouez 2001 Webster</Field> 
                <Field Name="ABC_Floor">02</Field>
                <Field Name="ABC_Room">002B</Field>
            </FieldList>
        </BusinessObject>
    </RelatedBusinessObjectList>
    </BusinessObject>
</BusinessObjectList>
</Transaction>

Example XSLT that can pull out a single building:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-16" indent="yes"/> 
<xsl:template match="Building">
    <xsl:element name="FMRequest">
        <xsl:attribute name="ID"><xsl:value-of select="BuildingName"/></xsl:attribute>
        <xsl:attribute name="TimeStamp"><xsl:value-of select="TimeStamp"/></xsl:attribute>
        <xsl:attribute name="Encryption"><xsl:text>false</xsl:text></xsl:attribute>
        <xsl:element name="Origin">
            <xsl:text>PMLocationImport</xsl:text>
        </xsl:element>
        <xsl:element name="Destination">
            <xsl:text>FI</xsl:text>
        </xsl:element>
        <xsl:element name="Transaction">
            <xsl:attribute name="Type"><xsl:text>UpdateAdd</xsl:text></xsl:attribute>
            <xsl:element name="BusinessObjectList">
                <!--<xsl:apply-templates/>-->
            </xsl:element>
        </xsl:element>
        <xsl:element name="BusinessObject">
            <xsl:attribute name="Name"><xsl:text>LocationGroup.EmployeeSite</xsl:text></xsl:attribute>
            <BusinessObjectList>
                <BusinessObject Name="LocationGroup.EmployeeSite">
                    <xsl:element name="Field">
                        <xsl:attribute name="Name"><xsl:text>ABC_PropertyManagementName</xsl:text></xsl:attribute>
                        <xsl:attribute name="identifier"><xsl:text>true</xsl:text></xsl:attribute>
                        <xsl:attribute name="UpdateOverride"><xsl:text>None</xsl:text></xsl:attribute>
                        <xsl:value-of select="BuildingName"/>
                    </xsl:element>
                    <xsl:element name="Field">
                        <xsl:attribute name="Name"><xsl:text>[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Purpose</xsl:text></xsl:attribute>
                        <xsl:text>Work</xsl:text>
                    </xsl:element>
                    <xsl:element name="Field">
                        <xsl:attribute name="Name"><xsl:text>[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Address</xsl:text></xsl:attribute>
                        <xsl:value-of select="BuildingAddress"/>
                    </xsl:element>
                    <xsl:element name="Field">
                        <xsl:attribute name="Name"><xsl:text>[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.City</xsl:text></xsl:attribute>
                        <xsl:value-of select="BuildingCity"/>
                    </xsl:element>
                    <xsl:element name="Field">
                        <xsl:attribute name="Name"><xsl:text>[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.State</xsl:text></xsl:attribute>
                        <xsl:value-of select="BuildingStateCode"/>
                    </xsl:element>
                    <xsl:element name="Field">
                        <xsl:attribute name="Name"><xsl:text>[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Zip</xsl:text></xsl:attribute>
                        <xsl:value-of select="ZipCode"/>
                    </xsl:element>
                </BusinessObject>
            </BusinessObjectList>
        </xsl:element>
    </xsl:element>
</xsl:template>

I know I need to use some for-each and keys, but I am unsure on the next steps to take to get this to group correctly.

1

1 Answers

0
votes

How about this style-sheet? Most of it is straight-forward templates. Floors are grouped using Muenchian grouping.

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/> 

<xsl:key name="floor" match="Room" use="FloorName" />  

<xsl:template match="/">
 <Transaction Type="UpdateAdd">
  <BusinessObjectList>
    <xsl:apply-templates select="File/Building"/> 
  </BusinessObjectList>
 </Transaction>
</xsl:template>

<xsl:template match="Building">
    <BusinessObject Name="LocationGroup.EmployeeSite">
        <FieldList>
          <Field Name="ABC_PropertyManagementName" identifier="true" UpdateOverride="None"><xsl:value-of select="BuildingName" /></Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Purpose">Work</Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Address"><xsl:value-of select="BuildingAddress" /></Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.City"><xsl:value-of select="BuildingCity" /></Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.State"><xsl:value-of select="BuildingStateCode" /></Field> 
            <Field Name="[EmployeeSiteContainsAddress,PrimaryAddressLink]Address.Mail.Zip"><xsl:value-of select="ZipCode" /></Field> 
        </FieldList>
    <RelatedBusinessObjectList>
      <xsl:for-each select="Room[ generate-id() =
                                  generate-id( key('floor',FloorName)[1]) ]">   
       <BusinessObject Name="LocationGroup.ABC_Floor">
        <FieldList>
         <Field Name="ABC_Building" identifier="true" UpdateOverride="None"><xsl:value-of select="../BuildingName" /></Field> 
         <Field Name="ABC_Floor"><xsl:value-of select="FloorName" /></Field>
        </FieldList>
       </BusinessObject>  
      </xsl:for-each>
      <xsl:apply-templates select="Room" />
    </RelatedBusinessObjectList>
    </BusinessObject>
</xsl:template>

<xsl:template match="Room">
 <BusinessObject Name="LocationGroup.ABC_Room">
  <FieldList>
   <Field Name="ABC_RoomID" identifier="true" UpdateOverride="None"><xsl:value-of select="ID" /></Field>
    <Field Name="ABC_Building"><xsl:value-of select="../BuildingName" /></Field> 
   <Field Name="ABC_Floor"><xsl:value-of select="FloorName" /></Field>
   <Field Name="ABC_Room"><xsl:value-of select="Name" /></Field>
  </FieldList>
 </BusinessObject>
</xsl:template>

</xsl:stylesheet>