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
--~------------------------------------------------------------------
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>
--~--