 |
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead. |
Welcome to the p2p.wrox.com Forums.
You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
|
|
|

June 14th, 2007, 12:10 AM
|
Registered User
|
|
Join Date: Jun 2007
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Selecting multiple elements from the source XML
Hi,
I am new to XSLT. I am trying to select multiple PersDriver elements from the source XML using XSLT. Here is how my XSLT looks like:
<?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:template match="/ACORD">
<policy>
<pos_policy>
â¦â¦â¦â¦â¦â¦â¦â¦
</pos_policy>
<drivers>
<xsl:for-each select="/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness[PersDriver/@id]">
<driver>
<driver_number>
<xsl:value-of select="substring-after(/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver/@id, 'PersDriver')"/>
</driver_number>
<first_name>
<xsl:value-of select="/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver/GeneralPartyInfo/NameInfo/PersonName/GivenName"/>
</first_name>
<last_name>
<xsl:value-of select="/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver/GeneralPartyInfo/NameInfo/PersonName/Surname"/>
</last_name>
</driver>
</xsl:for-each>
</drivers>
</policy>
</xsl:template>
<xsl:template match="PersDriver">
<xsl:value-of select="."/>
</xsl:template>
</xsl:stylesheet>
Where my source XML has three driver elements:
<PersDriver id=âPersDriver1â>
........
</PersDriver>
<PersDriver id=âPersDriver2â>
........
</PersDriver>
<PersDriver id=âPersDriver3â>
........
</PersDriver>
However, no matter what I do, it selects only driver1. Driver 2 and 3 are never selected into the output.
I also tried this syntax:
<drivers>
<xsl:for-each select="/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness[PersDriver/@id='PersDriver2']">
<xsl:call-template name="OutputDriver"/>
</xsl:for-each>
</drivers>
<xsl:template name="OutputDriver">
<driver>
<driver_number>
<xsl:value-of select="substring-after(/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver/@id, 'PersDriver')"/>
</driver_number>
â¦â¦â¦â¦â¦â¦â¦â¦â¦â¦.
</driver>
It always picks the driver# 1.
Then I tried the following:
<drivers>
<xsl:for-each select="range[@id_range=('1','2','3','4')]">
<xsl:variable name="driverId">
<xsl:value-of select="substring-after(/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver/@id, 'PersDriver')"/>
</xsl:variable>
<xsl:for-each select="/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver">
<xsl:choose>
<xsl:when test="$driverId='1'">
<xsl:element name="driver_number">
<xsl:value-of select="substring-after(/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver/@id, 'PersDriver')"/>
</xsl:element> </xsl:when>
<xsl:when test="$driverId='2'">
<xsl:element name="driver_number">
<xsl:value-of select="substring-after(/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver/@id, 'PersDriver')"/>
</xsl:element> </xsl:when>
</xsl:choose>
</xsl:for-each>
</xsl:for-each>
</drivers>
and I got the following error:
javax.xml.transform.TransformerException: javax.xml.transform.TransformerException: Expected ), but found: ,
I am also not sure if the above syntax will select all the driver elements?
Any help will be greatly appreciated! Thanks in advance!!
Best regards,
mkansal
|

June 14th, 2007, 02:52 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
You're doing:
<xsl:for-each select="/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness[PersDriver/@id]">
...
<xsl:value-of select="substring-after(/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver/@id, 'PersDriver')"/>
within a for-each, you usually want to select relative to the current node being processed by the for-each, whereas you're selecting from the top of the document (that's what the leading "/" means). Change it to
<xsl:value-of select="substring-after(PersDriver/@id, 'PersDriver')"/>
A 2.0 processor here would give you an error, because the argument to substring-after has to be a single string. But a 1.0 processor simply takes the first node selected, and ignores the rest.
This syntax:
range[@id_range=('1','2','3','4')]
is valid in XPath 2.0 but not in 1.0, and I think this accounts for the error message - so you appear to be using a 1.0 processor.
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
|

June 14th, 2007, 10:40 AM
|
Registered User
|
|
Join Date: Jun 2007
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Hello Mr. Kay,
Thanks a lot for your response! I tried the following, as you suggested:
<drivers>
<xsl:for-each select="/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness[PersDriver/@id]">
<driver>
<driver_number>
<xsl:value-of select="substring-after(PersDriver/@id, 'PersDriver')"/>
</driver_number>
</driver>
</xsl:for-each>
</drivers>
</xsl:template>
<xsl:template match="PersDriver">
<xsl:value-of select="."/>
</xsl:template>
It's working fine for the first driver. However, the problem is that it's selecting only the 1st driver. It's not selcting the other two drivers from the source XML, even though I am using 'for-each'. Could you please tell what do I need to do extra to make this work?
Thanks much!
Best Regards,
mkansal
|

June 14th, 2007, 10:56 AM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
Perhaps PersAutoLineBusiness only has one PersDriver child? You haven't actually shown us your source data.
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
|

June 14th, 2007, 12:00 PM
|
Registered User
|
|
Join Date: Jun 2007
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Hello Mr. Kay,
My source XML file is very big. However, here are some of the data elements showing the 3 'PersDriver' driver elements:
- <ACORD>
+ <SignonRq>
- <SignonPswd>
- <PersAutoLineBusiness>
- <PersDriver id="PersDriver1">
- <GeneralPartyInfo>
+ <NameInfo>
- <PersonName>
</PersonName>
</NameInfo>
+ <Addr>
<AddrTypeCd>StreetAddress</AddrTypeCd>
<Addr1>223 summer</Addr1>
<Addr2>apt #1</Addr2>
<City>Seattle</City>
<StateProvCd>WA</StateProvCd>
<PostalCode>98104</PostalCode>
<County>KING</County>
</Addr>
- <Communications>
- <PhoneInfo>
<CommunicationUseCd>Home</CommunicationUseCd>
<PhoneNumber>+1-555-5555555+123</PhoneNumber>
</PhoneInfo>
</Communications>
</GeneralPartyInfo>
+ <DriverInfo>
- <PersonInfo>
<GenderCd></GenderCd>
<BirthDt></BirthDt>
<MaritalStatusCd></MaritalStatusCd>
</PersonInfo>
- <DriversLicense>
<LicensedDt>1986-10-11</LicensedDt>
<DriversLicenseNumber>akdfisd85226</DriversLicenseNumber>
<FirstLicensedCurrentStateDt>1986-10-11</FirstLicensedCurrentStateDt>
<StateProvCd>WA</StateProvCd>
<CountryCd>US</CountryCd>
</DriversLicense>
</DriverInfo>
+ <PersDriverInfo VehPrincipallyDrivenRef="PersVeh1">
<DefensiveDriverDt>2007-05-11</DefensiveDriverDt>
<DefensiveDriverCd>N</DefensiveDriverCd>
<DistantStudentInd>0</DistantStudentInd>
</PersDriverInfo>
</PersDriver>
- <PersDriver id="PersDriver2">
- <GeneralPartyInfo>
- <NameInfo>
- <PersonName>
</PersonName>
</NameInfo>
</GeneralPartyInfo>
+ <DriverInfo>
- <PersonInfo>
<GenderCd></GenderCd>
<BirthDt></BirthDt>
<MaritalStatusCd></MaritalStatusCd>
<OccupationClassCd></OccupationClassCd>
</PersonInfo>
- <DriversLicense>
<LicensedDt>1991-05-01</LicensedDt>
<DriversLicenseNumber>akdfisd85253</DriversLicenseNumber>
<FirstLicensedCurrentStateDt>1991-05-01</FirstLicensedCurrentStateDt>
<StateProvCd>WA</StateProvCd>
<CountryCd>US</CountryCd>
</DriversLicense>
</DriverInfo>
+ <PersDriverInfo VehPrincipallyDrivenRef="PersVeh2">
<DefensiveDriverDt>2007-05-11</DefensiveDriverDt>
<DefensiveDriverCd>Y</DefensiveDriverCd>
<DistantStudentInd>0</DistantStudentInd>
</PersDriverInfo>
</PersDriver>
- <PersDriver id="PersDriver3">
- <GeneralPartyInfo>
- <NameInfo>
+ <PersonName>
</PersonName>
</NameInfo>
</GeneralPartyInfo>
+ <DriverInfo>
- <PersonInfo>
<GenderCd></GenderCd>
<BirthDt></BirthDt>
<MaritalStatusCd></MaritalStatusCd>
<OccupationClassCd></OccupationClassCd>
</PersonInfo>
- <DriversLicense>
<LicensedDt>1999-04-11</LicensedDt>
<DriversLicenseNumber>akdfisd85251</DriversLicenseNumber>
<FirstLicensedCurrentStateDt>1999-04-11</FirstLicensedCurrentStateDt>
<StateProvCd>WA</StateProvCd>
<CountryCd>US</CountryCd>
</DriversLicense>
</DriverInfo>
</PersDriverInfo>
</PersDriver>
- <PersVeh id="PersVeh1" RatedDriverRef="PersDriver1" LocationRef="Location1">
<Manufacturer>MAZDA</Manufacturer>
<Model>B2300 BASE/B2300 4 PK</Model>
<ModelYear>2005</ModelYear>
<VehBodyTypeCd>PU</VehBodyTypeCd>
.................
</ACORD>
Thanks!
Best regards,
mkansal
|

June 14th, 2007, 12:09 PM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
I don't really know what this +/- notation is supposed to mean, but your path expression contains InsuranceSvcRq/PersAutoPolicyQuoteInqRq and I don't see either of those elements in your source, so I'm surprised it selects anything at all.
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
|

June 14th, 2007, 12:30 PM
|
Registered User
|
|
Join Date: Jun 2007
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Sorry, here it is again. The '+' sign means, the element is expandable and has children. I opened the XML in browser and collapsed some elements to make the source XML shorter. That's why you are seeing those '+' and '-' signs.
- <ACORD>
+ <SignonRq>
- <SignonPswd>
- <InsuranceSvcRq>
<RqUID>8D6B1F3F-0C55-4018-A6DF-6B0030ED6DEE</RqUID>
<SPName></SPName>
- <PersAutoPolicyQuoteInqRq>
<RqUID>8D6B1F3F-0C55-4018-A6DF-6B0030ED6DEE</RqUID>
<TransactionRequestDt>2007-05-11T12:58:041-06:00</TransactionRequestDt>
<TransactionEffectiveDt>2008-04-13</TransactionEffectiveDt>
<CurCd></CurCd>
+ <Producer>
- <GeneralPartyInfo>
- <NameInfo>
- <CommlName>
<CommercialName></CommercialName>
</CommlName>
</NameInfo>
- <Addr>
<Addr1>1223</Addr1>
<Addr2>456 test</Addr2>
<StateProvCd>WA</StateProvCd>
<PostalCode />
</Addr>
</GeneralPartyInfo>
- <ProducerInfo>
<ContractNumber>testu</ContractNumber>
</ProducerInfo>
</Producer>
+ <InsuredOrPrincipal>
- <GeneralPartyInfo>
- <NameInfo>
</GeneralPartyInfo>
- <InsuredOrPrincipalInfo>
<InsuredOrPrincipalRoleCd>Insured</InsuredOrPrincipalRoleCd>
- <PersonInfo>
<GenderCd></GenderCd>
<BirthDt></BirthDt>
<MaritalStatusCd></MaritalStatusCd>
</PersonInfo>
</InsuredOrPrincipalInfo>
</InsuredOrPrincipal>
+ <PersPolicy>
...........
</PersPolicy>
- <PersAutoLineBusiness>
- <PersDriver id="PersDriver1">
- <GeneralPartyInfo>
+ <NameInfo>
- <PersonName>
</PersonName>
</NameInfo>
+ <Addr>
<AddrTypeCd>StreetAddress</AddrTypeCd>
<Addr1>223 summer</Addr1>
<Addr2>apt #1</Addr2>
<City>Seattle</City>
<StateProvCd>WA</StateProvCd>
<PostalCode>98104</PostalCode>
<County>KING</County>
</Addr>
- <Communications>
- <PhoneInfo>
<CommunicationUseCd>Home</CommunicationUseCd>
<PhoneNumber>+1-555-5555555+123</PhoneNumber>
</PhoneInfo>
</Communications>
</GeneralPartyInfo>
+ <DriverInfo>
- <PersonInfo>
<GenderCd></GenderCd>
<BirthDt></BirthDt>
<MaritalStatusCd></MaritalStatusCd>
</PersonInfo>
- <DriversLicense>
<LicensedDt>1986-10-11</LicensedDt>
<DriversLicenseNumber>akdfisd85226</DriversLicenseNumber>
<FirstLicensedCurrentStateDt>1986-10-11</FirstLicensedCurrentStateDt>
<StateProvCd>WA</StateProvCd>
<CountryCd>US</CountryCd>
</DriversLicense>
</DriverInfo>
+ <PersDriverInfo VehPrincipallyDrivenRef="PersVeh1">
<DefensiveDriverDt>2007-05-11</DefensiveDriverDt>
<DefensiveDriverCd>N</DefensiveDriverCd>
<DistantStudentInd>0</DistantStudentInd>
</PersDriverInfo>
</PersDriver>
- <PersDriver id="PersDriver2">
- <GeneralPartyInfo>
- <NameInfo>
- <PersonName>
</PersonName>
</NameInfo>
</GeneralPartyInfo>
+ <DriverInfo>
- <PersonInfo>
<GenderCd></GenderCd>
<BirthDt></BirthDt>
<MaritalStatusCd></MaritalStatusCd>
<OccupationClassCd></OccupationClassCd>
</PersonInfo>
- <DriversLicense>
<LicensedDt>1991-05-01</LicensedDt>
<DriversLicenseNumber>akdfisd85253</DriversLicenseNumber>
<FirstLicensedCurrentStateDt>1991-05-01</FirstLicensedCurrentStateDt>
<StateProvCd>WA</StateProvCd>
<CountryCd>US</CountryCd>
</DriversLicense>
</DriverInfo>
+ <PersDriverInfo VehPrincipallyDrivenRef="PersVeh2">
<DefensiveDriverDt>2007-05-11</DefensiveDriverDt>
<DefensiveDriverCd>Y</DefensiveDriverCd>
<DistantStudentInd>0</DistantStudentInd>
</PersDriverInfo>
</PersDriver>
- <PersDriver id="PersDriver3">
- <GeneralPartyInfo>
- <NameInfo>
+ <PersonName>
</PersonName>
</NameInfo>
</GeneralPartyInfo>
+ <DriverInfo>
- <PersonInfo>
<GenderCd></GenderCd>
<BirthDt></BirthDt>
<MaritalStatusCd></MaritalStatusCd>
<OccupationClassCd></OccupationClassCd>
</PersonInfo>
- <DriversLicense>
<LicensedDt>1999-04-11</LicensedDt>
<DriversLicenseNumber>akdfisd85251</DriversLicenseNumber>
<FirstLicensedCurrentStateDt>1999-04-11</FirstLicensedCurrentStateDt>
<StateProvCd>WA</StateProvCd>
<CountryCd>US</CountryCd>
</DriversLicense>
</DriverInfo>
</PersDriverInfo>
</PersDriver>
- <PersVeh id="PersVeh1" RatedDriverRef="PersDriver1" LocationRef="Location1">
<Manufacturer>MAZDA</Manufacturer>
<Model>B2300 BASE/B2300 4 PK</Model>
<ModelYear>2005</ModelYear>
<VehBodyTypeCd>PU</VehBodyTypeCd>
.................
</PersAutoPolicyQuoteInqRq>
</InsuranceSvcRq>
</ACORD>
Thanks!
mkansal
|

June 14th, 2007, 01:01 PM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
>However, here are some of the data elements showing the 3 'PersDriver' driver elements:
You aren't iterating over the PersDriver elements, you are iterating over the PersAutoLineBusiness elements. When you do
<xsl:for-each select="a/b/c[d/e]">
then you are iterating over the c elements where the predicate d/e is satisfied. You have only one c element.
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
|

June 14th, 2007, 03:14 PM
|
Registered User
|
|
Join Date: Jun 2007
Posts: 9
Thanks: 0
Thanked 0 Times in 0 Posts
|
|
Thanks for your response! Now I used the following:
<xsl:for-each select="/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver[@id]">
<driver>
<driver_number>
<xsl:value-of select="substring-after(/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver/@id, 'PersDriver')"/>
</driver_number>
</driver>
</xsl:for-each>
Now I am getting the same driver (the first one) three times. If I try the following:
<xsl:for-each select="/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver[@id=('1','2')]">
<driver>
<driver_number>
<xsl:value-of select="substring-after(/ACORD/InsuranceSvcRq/PersAutoPolicyQuoteInqRq/PersAutoLineBusiness/PersDriver/@id, 'PersDriver')"/>
</driver_number>
</driver>
It gives me TransformerException. Is the above syntax correct? I am using javax.xml.transform API. Could you please tell me if there is any other API that I can use for this purpose, which won't give this error or which jar file should I use?
Thanks again!
mkansal
|

June 14th, 2007, 04:49 PM
|
 |
Wrox Author
|
|
Join Date: Apr 2004
Posts: 4,962
Thanks: 0
Thanked 292 Times in 287 Posts
|
|
For goodness sake. "It gives me TransformerException". Is that all? No other error message? If there's no other error message then you're doing something badly wrong that causes it to be suppressed. If there is another error message, then doesn't it occur to you that I might be able to help you more easily if you tell me what the error message is?
Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
|
|
 |