Home > OS >  XSLT help grouping or matching nodes
XSLT help grouping or matching nodes

Time:10-15

I have this XML, that is a series of ContactInfo nodes, some contain the PostAddr, and some contain the PhoneNum. I have to match the ContactInfo node that contains the address with the one that contains the PhoneNum like this - the AddrSource tag value (in the ContactInfo nodes that contain address) should match the PhoneNum Source attribute value(from the ContactInfo nodes that contain phones).

This is a sample of the XML:

<ContactInfo Source="MB" EffDt="2022-10-11">
        <PostAddr>
            <StreetNum>xxx</StreetNum>
            <StreetName>ATLANTA</StreetName>
            <StreetType>HWY</StreetType>
            <Apt>099</Apt>
            <City>MONTGOMERY</City>
            <StateProv>AL</StateProv>
            <PostalCode>1000</PostalCode>
            <County>MONTGOMERY</County>
            <AddrType>S</AddrType>
            <ReportedDt>2019-08-09</ReportedDt>
            <AddrSource>3</AddrSource>
            <AddrCreatedDt>2019-07-22</AddrCreatedDt>
        </PostAddr>
    </ContactInfo>
    <ContactInfo Source="MB" EffDt="2022-10-11">
        <PostAddr>
            <StreetNum>09521</StreetNum>
            <StreetName>STANTON</StreetName>
            <StreetType>WAY</StreetType>
            <Apt>APT 19080</Apt>
            <City>PRATTVILLE</City>
            <StateProv>AL</StateProv>
            <PostalCode>111-111</PostalCode>
            <County>AUTAUGA</County>
            <AddrType>H</AddrType>
            <ReportedDt>2019-04-09</ReportedDt>
            <AddrSource>4</AddrSource>
            <AddrCreatedDt>2019-04-03</AddrCreatedDt>
        </PostAddr>
    </ContactInfo>
    <ContactInfo Source="MB" EffDt="2022-10-11">
        <PhoneNum Source="3" EffDt="2022-10-11">
            <PhoneType>OTHER   </PhoneType>
            <Phone>123224434</Phone>
        </PhoneNum>
    </ContactInfo>
    <ContactInfo Source="MB" EffDt="2022-10-11">
        <PhoneNum Source="4" EffDt="2022-10-11">
            <PhoneType>OTHER   /WIRELESS</PhoneType>
            <Phone>30000</Phone>
        </PhoneNum>
    </ContactInfo>

Ultimately I need to be able to make a table in this format:

<table>
    <tr>
        <td>Address</td>
        <td>Phone</td>
    </tr>
</table>

What should be my approach here? I have been mainly working with for-each loops and choose but I can't seem to find a way to make them work here. I looked a bit into grouping but I wasn't able to apply that either, so I'm a bit stuck with this. Any help would be greatly appreciated.

CodePudding user response:

XSLT has a built-in key mechanism for resolving cross-references. Here's a minimal example:

XSLT 1.0

<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="phone" match="PhoneNum" use="@Source" />

<xsl:template match="/*">
    <table border="1">
        <xsl:for-each select="ContactInfo/PostAddr">
            <tr>
                <td>
                    <xsl:value-of select="City"/>
                </td>
                <td>
                    <xsl:value-of select="key('phone', AddrSource)/Phone"/>
                </td>
            </tr>
        </xsl:for-each>
    </table>
</xsl:template>

</xsl:stylesheet>

Applied to your input example - after adding a root element! - this will return:

Result

<?xml version="1.0" encoding="UTF-8"?>
<table border="1">
   <tr>
      <td>MONTGOMERY</td>
      <td>123224434</td>
   </tr>
   <tr>
      <td>PRATTVILLE</td>
      <td>30000</td>
   </tr>
</table>
  • Related