Subject: Re: [xsl] Restrict Key to specific parent From: Wendell Piez <wapiez@xxxxxxxxxxxxxxxx> Date: Wed, 29 Nov 2006 16:03:16 -0500 |
<xsl:variable name="Prod-names" select="ProfileInfo/@name | Prod/@name"/> <!-- collect the ProfileInfo and Prod names (whichever you have here) -->
Cheers, Wendell
Hello, This is as simple of an example, hitting the main scenarios, I could come up with.
I will try and be as clear and unambiguous as possible. I did research throughout the xsl-list archive and found posts that were close, but did not really hit my issue here. I will start with an input xml, show the output expected and then show you what I tried and it's short comings. So here goes.
Input XML: <Root> <Info> <Prod name="Red"/> <Prod name="Blue"/> <Prod name="Green"/> </Info> <Title>Test Document</Title> <Section> <Paragraph> This is regular text for these product: <Name/> <Profile> <ProfileInfo Name="Blue"/> <!-- The issue here is that we cannot be sure how deep the <Name/> element is from the <Profile> and <ProfileInfo> element --> This is text associated with Prod Profile: <bold><Name/></bold> </Profile> This is text after the profile that is for all Prods: <Name/> <Profile> <ProfileInfo Name="Red"/> <ProfileInfo Name="Green"/> This is text associated with Product Profile for <Name/> </Profile> </Paragraph> <Paragraph> This is some more text. <Profile> <ProfileInfo Name="Blue"/> More text associated with <Name/> </Profile> </Paragraph> </Section> <Section> <ProfileInfo Name="Green"/> <Paragraph> This is text that goes along with this section for <Name/> </Paragraph> </Section> </Root>
Expected Output:
<Title>Test Document</Title>
<Section> <Paragraph> This is regular text for these products: Red, Blue, Green
<Profile> This is text associated with Product Profile for <bold>Blue</bold> </Profile>
This is text after the profile that is for all products: Red, Blue, Green <Profile> This is text associated with Product Profile for Red, Green </Profile>
</Paragraph>
<Paragraph> This is some more text.
<Profile> More text associated with Blue </Profile>
</Paragraph> </Section>
<Section> <Profile> This is text that goes along with this section for Green </Profile> </Section>
Ok, so the rules that we want to abide by are as follows: (The only template that I am having trouble with is the <Name> tag, I can correctly I identify and resolve all other tags)
1) If there is a <Name/> Element within a <Profile> element, then take all the ProfileInfo elements that are children of the <Profile> element and display their @Name attribute uniquely and separated by commas. 2) If there is a <Name/> Element within a <Section> element, and the <Section> has a <ProfileInfo> in it (the ProfileInfo will have to come directly after the <Section> element defined by the schema.) then output only the @Name of the <ProfileInfo>(s) associated with that particular <Section> 3) If there is a <Name/> Element that does not reside in a <Profile> element (which has a profile element) or within a <Section> element that is profiled (has a <ProfileInfo> tag) then we want to output all Prod/@name separated by commas and non repeating.
The main question is: How to scope the <xsl:key>'s when I'm in the <xsl:for-each> such that only the profiles of that specific section are looked at, not the entire document which is happening here.
Here's what I have: (My namespace is _ for convenience)
<xsl:key name="distinct-name" match="_:Prod" use="@name" /> <xsl:key name="distinct-name-profiled" match="_:ProfileInfo" use="@Name" />
<xsl:template match="_:Name"> <xsl:choose> <xsl:when test="ancestor::_:ProductProfile">
<xsl:for-each select="preceding::_:ProfileInfo[generate-id(.)=generate-id(key('distinct-name-profiled',@Name)[1])]"> <span> <xsl:value-of select="@Name"/> <xsl:if test="position() != last()">, </xsl:if> </span> </xsl:for-each>
</xsl:when> <xsl:when test="not(ancestor::_:ProductProfile) and preceding::_:Section">
<xsl:for-each select="preceding::_:ProfileInfo[generate-id()=generate-id(key('distinct-name-profiled',@Name)[1])]"> <span> <xsl:value-of select="@Name"/> <xsl:if test="position() != last()">, </xsl:if> </span> </xsl:for-each>
</xsl:when> <xsl:otherwise>
<xsl:for-each select="//_:Prod[generate-id()=generate-id(key('distinct-name',@name))]"> <span> <xsl:value-of select="@name"/> <xsl:if test="position() != last()">, </xsl:if> </span> </xsl:for-each>
</xsl:otherwise> </xsl:choose>
</xsl:template>
Please let me know if there is anything else that you man need.
Thanks again for all your time, -Ty
====================================================================== Wendell Piez mailto:wapiez@xxxxxxxxxxxxxxxx Mulberry Technologies, Inc. http://www.mulberrytech.com 17 West Jefferson Street Direct Phone: 301/315-9635 Suite 207 Phone: 301/315-9631 Rockville, MD 20850 Fax: 301/315-8285 ---------------------------------------------------------------------- Mulberry Technologies: A Consultancy Specializing in SGML and XML ======================================================================
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] Restrict Key to specific pare, Ty Molchany | Thread | [xsl] Processing empty nodes in XSL, Chris Griffin |
RE: [xsl] Fwd: Multiple OR Expressi, cknell | Date | [xsl] Processing empty nodes in XSL, Chris Griffin |
Month |