[Home] [By Thread] [By Date] [Recent Entries]
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.
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
|

Cart



