xsl-list
[Top] [All Lists]

Re: [xsl] Multiple Template Matchingm, Attributes & Complex XML

2011-02-25 12:03:10
Here's a modified version of your transform that I think should answer
your questions.  Notes, below.

<?xml version="1.0" encoding="iso-8859-1" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
xmlns:d="urn:stylesheet-data" exclude-result-prefixes="d">
    <xsl:output method="xml"/>

    <xsl:param name="genderTCs" select="document('')/*/d:codes/d:gender"/>
    <xsl:param name="stateTCs" select="document('stateTCs.xml')/*/*"/>
    <!-- <states><state tc="1">AL</state>...</states> -->

    <d:codes>
        <d:gender tc="1">Male</d:gender>
        <d:gender tc="2">Female</d:gender>
    </d:codes>

    <xsl:template match="TXLife">
        <TXLife>
            <UserAuthRequest>elements omitted </UserAuthRequest>
            <TXLifeRequest>
                <OLifE>
                    <Holding id="Holding_167392">elements omitted
                        <Policy>elements omitted</Policy>
                    </Holding>
                    <Party id="InsuredParty_5293884">
                        <xsl:apply-templates select="Person"/>
                        <xsl:apply-templates select="Address"/>
                        <Phone>elements omitted</Phone>
                    </Party>
                </OLifE>
            </TXLifeRequest>
        </TXLife>
    </xsl:template>

    <xsl:template match="Person">
        <Person>
            <xsl:copy-of select="FirstName | LastName"/>
            <Gender tc="{$genderTCs[. = current()/Gender]/@tc}">
                <xsl:apply-templates select="Gender/node()"/>
            </Gender>
            <xsl:copy-of select="BirthDate"/>
            <DriversLicenseNum>none</DriversLicenseNum>
            <DriversLicenseState tc="17">IL</DriversLicenseState>
        </Person>
        <!--<xsl:apply-templates select="following-sibling::Address[1]"/>-->
    </xsl:template>

    <xsl:template match="Address">
        <Address>elements omitted
            <AddressStateTC tc="{$stateTCs[. = current()/AddressStateTC]/@tc}">
                <xsl:apply-templates select="AddressStateTC/node()"/>
            </AddressStateTC>
        </Address>
    </xsl:template>
</xsl:stylesheet>

Based on the input/output sample you provided, it seems like you
really want to generate an output <TXLife> for each input <TXLife>.
If you really want to generate a <TXLife> for each <Person>, as your
version was doing, put the contents of the TXLife template back into
the Person template, replacing the <xsl:apply-templates
select="Person"/> with the current contents of the Person template,
removing the <xsl:apply-templates select="Address"/> line and
uncommenting the line at the end of the Person template.

Other changes:

1. Rather than recreating nodes, you can just use <xsl:copy-of/> to
copy them into the output.

2. Be careful using <xsl:value-of/>, which always produces a string,
squashing any markup.  Using <xsl:apply-templates/> is usually safer,
as it will recursively process any markup children that might occur
(though this is usually more of an issue with document-style XML,
which often has inline markup like "blah <b>bold</b> blah").

3. Not sure what you intended with the <xsl:apply-templates> tag
around the <Person> tag.  The <xsl:apply-templates> instruction is not
allowed any children other than <xsl:with-param> or <xsl:sort>.

4. You can embed data markup at the top level of the XSL transform,
provided it is in a namespace, as shown with the gender lookup table.
You can also read it in from an external file (ideally located next to
the transform on disk, so it can be found at runtime), as shown with
the state lookup table, whose expected format is shown in the comment.
 Because the variables used to execute the lookups are declared as
parameters, you can, alternatively, pass in an in-memory
document/node, perhaps built from the result of a SQL query (using
XmlDataDocument).

-Brandon :)


On Fri, Feb 25, 2011 at 12:13 PM, Jeffry Proctor 
<jpgmt(_at_)sbcglobal(_dot_)net> wrote:
ASP.Net 2008, Linq XmlCompiledTransform, XSLT ver 1.0 I assume?

1. Limited as I am, the Person node/element & attribute is updating correctly;
How do I add other node/element?
I assume it will be to remove Person as the top level match, but I'm not 
finding
examples for making XML, many for HTML and mutilple tables sometimes nesting,
but for some reason that doesn't speak to me.

2. Is there a way to have another xml file as a lookup list for attributes 
like
gender typeCode tc or state typeCode tc so that the one XSL is easier to 
manage?
(very low priority at this time, worst case, I can return those values
discretely based on an SQL lookup that returns only the one state:tc relation
value.)

XML Output Frag...
      </Holding>
      <Party id="InsuredParty_5293884">
        <Person>
          <FirstName>Rogerina</FirstName>
          <LastName>Proctor</LastName>
          <Gender tc="1">Male</Gender>
          <BirthDate>1975-01-01</BirthDate>
          <DriversLicenseNum>none</DriversLicenseNum>
          <DriversLicenseState tc="17">IL</DriversLicenseState>
        </Person>
        <Address> <!-- currently hardcoded... -->
          <AddressTypeCode tc="1">Residence</AddressTypeCode>
          <Line1>123 Superior Street</Line1>
          <City>City</City>
          <AddressStateTC tc="">
          </AddressStateTC>
          <Zip>89089</Zip>
        </Address>


XML Frag...
<?xml version="1.0" encoding="iso-8859-1"?>
<TXLife>
    <Person>
        <FirstName>Rogerina</FirstName>
        <LastName>Proctor</LastName>
        <Gender>Male</Gender>
        <BirthDate>1975-01-01</BirthDate>
    </Person>
   <!-- How to add: AddressStateTC to the XSL? -->
    <Address>
       <AddressStateTC>CA</AddressStateTC>
    </Address>
</TXLife>

 XSL Frag...
<?xml version="1.0" encoding="iso-8859-1" ?>
<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
    <xsl:output method="xml"/>
    <!-- this wroks ONLY for Person, how do I add other items to match
on: AddressStateTC -->
    <xsl:template match="Person">
        <TXLife>
            <UserAuthRequest>elements omitted </UserAuthRequest>
            <TXLifeRequest>
                <OLifE>
                    <Holding id="Holding_167392">elements omitted
                        </Policy>elements omitted</Policy>
                    </Holding>
                    <Party id="InsuredParty_5293884">
                        <xsl:apply-templates>
                            <Person>
                                <FirstName><xsl:value-of
select="FirstName"/></FirstName>
                                <LastName><xsl:value-of
select="LastName"/></LastName>
                                <Gender>
                                    <xsl:attribute name="tc">
                                        <xsl:choose>
                                            <xsl:when
test="Gender='Male'">1</xsl:when>
                                            <xsl:when
test="Gender='Female'">2</xsl:when>
                                        </xsl:choose>
                                    </xsl:attribute>
                                    <xsl:value-of select="Gender"/>
                                </Gender>
                                <BirthDate><xsl:value-of
select="BirthDate"/></BirthDate>
                                <DriversLicenseNum>none</DriversLicenseNum>
                                <DriversLicenseState
tc="17">IL</DriversLicenseState>
                            </Person>
                        </xsl:apply-templates>
                        <Address>elements omitted
                            <!--
                                  Important question: How do I add an Address
template?
                            -->
                            <AddressStateTC>
                                <xsl:attribute name="tc">
                                    <xsl:choose>
                                        <!-- this is a low priority 
question...
                                          Is there a way to add either another
XSL for adding the attribute?

                                        -->
                                        <xsl:when
test="AddressStateTC='AL'">1</xsl:when>
                                        <xsl:when
test="AddressStateTC='AK'">2</xsl:when>
                                        other states omitted...
                                    </xsl:choose>
                                </xsl:attribute>
                                <xsl:value-of select="AddressStateTC"/>
                            </AddressStateTC>
                        </Address>
                        <Phone>elements omitted</Phone>
                    </Party>
                </OLifE>
            </TXLifeRequest>
        </TXLife>
    </xsl:template>
</xsl:stylesheet>

TIA
JeffPGMT...

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: 
<mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--



--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>