Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Westi on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

xpath with many parent/child nodes

Status
Not open for further replies.

jba6511

Programmer
Jun 15, 2007
23
US
Thanks for helping me through all this xpath guys. I am slowly getting it. I now have a doc that is a little different from those that I have been working with. It looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<xmp:document
xmlns:xmp=" documentDate="2001-09-11">
<xmp:comment>Good Financial Standing</xmp:comment>
<Applicant xmp:phone="919.595.6765">
<name>James Smith</name>
<location>65th Street</location>
<city>San Fransisco</city>
<state>CA</state>
</Applicant>
<Applications>
<Approvals approvalNumber="3346">
<date>2004-09-04</date>
<loanAmount>1000</loanAmount>
<interestRate>07</interestRate>
</Approvals>
<Approvals approvalNumber="7632">
<date>2005-05-01</date>
<loanAmount>2000</loanAmount>
<interestRate>05</interestRate>
</Approvals>
</Applications>
<bank xmp:phone="919.565.1111">
<name>First Bank</name>
<location>123 Bank Place</location>
<city>San Fransisco</city>
<state>CA</state>
</bank>
</xmp:document>

I am trying to select all of the loanAmounts from the document. I have tried to isolate the node to just Applications and then work with the approvals child node. However, the various parent/child nodes are giving me trouble. This is what I have tried:

<xsl:template match="document">
<html>
<body>
<xsl:apply-templates select="document/Applications/Approvals"/>
</body>
</html>
</xsl:template>
<xsl:template match="Applications">
<p>
<xsl:for-each select="Applications">
<xsl:value-of select="@loanAmount"/>
<xsl:text> </xsl:text>
</xsl:for-each>
</p>
</xsl:template>
</xsl:stylesheet>
 
You perhaps need to investigate the [tt]//[/tt] XPath operator. This operator indicates that zero or more elements may occur between the slashes. So the XPath expression:
Code:
//loanAmount
will return a node set of all the loanAmount elements no matter where in the document they appear. As another example, if you want only loanAmount elements that are a descendant of an Applications element you could use either of these equivalent XPath expressions:
Code:
//Applications//loanAmount
//Applications/descendant-or-self::loanAmount
Does that help?

Tom Morrison
 
when I use the following syntax, it lists one number and not all of them. Does the xpath expression need to be used elsewhere in order to pick up all of the numbers?

<xsl:template match="document">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="Applications">
<p>
<xsl:value-of select="//@loanAmount"/>

</p>
</xsl:template>
</xsl:stylesheet>
 
also, I am still getting other data such as the comment and address listed as well instead of just the loan. What is causing this to be listed as I am only outputting the loan?
 
That ampersand (@) indicates you are selecting an attribute named loanAmount, but I see no such attributes in your example document.

jba6511 said:
also, I am still getting other data such as the comment and address listed as well instead of just the loan. What is causing this to be listed as I am only outputting the loan?
You are seeing the effect of built-in template rules which you may find described here. The usual 'cure' for this is to place the following template, which overrides the default copy-through behavior, as the last template in your stylesheet:
Code:
<xsl:template match="text()|@*">
</xsl:template>
This template catches the 'stray' text and attribute nodes before the built-in rules are invoked, and ignores them.

Tom Morrison
 
thanks, adding that last template match got rid of the rest of the text except the numbers. What if I wanted to select just the approval numbers? replacing //loanAmount with //@approvalNumber does not seem to work. Would I have to use a for-each to catch all the approval Numbers? Thanks again for helping me walk through this example.
 
Have you tried this?
Code:
//Approvals/@approvalNumber

[small]Warning: possible pendantry follows![/small]
Since [tt]//[/tt] is an abbreviation for descendant-or-self:: it makes sense that //@approvalNumber will not work. The ampersand is an abbreviation for the attribute:: axis, one would have to interpret //@approvalNumber as equivalent to /descendant-or-self::attribute::approvalNumber, which is not a valid XPath expression.

Tom Morrison
 
it still seems to only output one number instead of all the approval numbers. Any ideas?
 
This is what I have now in order to output all the approval numbers:

<xsl:template match="document">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="Applications">
<p>
<xsl:value-of select="//Approvals/@approvalNumber"/>
</p>
</xsl:template>

<xsl:template match="text()|@*">
</xsl:template>
</xsl:stylesheet>
 
Nevermind guys I got it working outputting all of the approval numbers. I need to use a for-each and then a value-of select=".". Thanks for the help.
 
OK last question, I swear. How do you select loan amount and interest for each approval? I can select and output all the loan amounts and then all the interest, but not the loan amount then interest, loan amount, interest, etc.
 
Please post you XSLT as it exists at this point. However, you might find the rather simple example here illuminating. (It gets both the title and artist on each itteration of the for-each.)

Tom Morrison
 
that tutorial is what I have been looking at for examples. The SAMS book does not seem to have alot of tutorials in it or examples to follow. I have managed to output the loan amount and the interest rate. However, I would like to format it so I can <xml:text>Loan Amount: </xml:text> and then lists the loan amount and then following the amount <xml:text>term</xml:text> for each one. I would also like to know how to select the applicants name, which is from the Applicant node as well as there address and loan amount. Here is the code I have so far which output the loan amount followed by the term:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl=" <xsl:eek:utput method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:template match="document">
<html>
<body>
<xsl:apply-templates/>
</body>
</html>
</xsl:template>
<xsl:template match="Applications">
<p>
<xsl:for-each select="//Approvals/loanAmount | //Approvals/interestRate">
<xsl:text> </xsl:text>
<xsl:value-of select="."/>
<xsl:text> </xsl:text>
<xsl:text> </xsl:text>
</xsl:for-each>
</p>
</xsl:template>

<xsl:template match="text()|@*">
</xsl:template>
</xsl:stylesheet>
 
Jumped ahead of myself again. I was able to figure out how to do names, loan amounts and addresses. Still can not figure out how to output the loan amounts and terms in a good format though. I do not know much html.
 
ok this is the last question pertaning to this example. I am trying to get the approval number that corresponds to the loan amount of 1000. From the previous help I have recieved here I am trying to use this syntax:

<xsl:template match="Applications">
<p>
<xsl:value-of select="@approvalNumber[parent::*/loanAmount/text()='1000']"/>
</p>
</xsl:template>

However it does not output anything. Is this because the parent, Approvals, it not being found using this statement. Do I need to explicity list it before @approvalNumber?

Last one guys I swear.

 
Reminder: >Last one guys I swear.

[tt] <xsl:template match="Applications">
<p>
<xsl:value-of select="[red]Approval/[/red]@approvalNumber[parent::*/loanAmount/text()='1000']"/>
</p>
</xsl:template>
[/tt]
 
Amendment

[tt] <xsl:template match="Applications">
<p>
<xsl:value-of select="Approval[red]s[/red]/@approvalNumber[parent::*/loanAmount/text()='1000']"/>
</p>
</xsl:template>
[/tt]
 
Further note

Equivalently in this case.
[tt]
<xsl:template match="Applications">
<p>
<xsl:value-of select="[blue]Approvals[loanAmount/text()='1000']/[/blue]@approvalNumber"/>
</p>
</xsl:template>
[/tt]
So you now see all.
 
sorry sorry I mistyped. It works fine. Thank you so much. I promise to leave you guys alone for awhile now with the questions.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top