UPDATE: 9-18-2012, late afternoon The 101.(a) are extra here, and are ancestor::*[@belcode] above the one I need. They are in the XML sample below, and I haven't been able to figure out how NOT to get them.
bad XML output sample:
<p style="I24">101.(a)(e)(1)(A) If the Attorney General determines that a licensee under this section has willfully violated any provision of this chapter or any regulation prescribed under this chapter, the Attorney General may—</p>
XSL where only the for-each with the belcode is behaving badly:
<xsl:choose>
<xsl:when test="../@display-inline='yes-display-inline'">
<xsl:for-each select="ancestor-or-self::*[@belcode!='' and not(../@belcode/text or ../@belcode/header)]/enum">
<xsl:value-of select="."/>
</xsl:for-each>
<xsl:for-each select="ancestor-or-self::*[@display-inline='yes-display-inline']/enum">
<xsl:value-of select="."/>
</xsl:for-each>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="../enum"/>
<xsl:text></xsl:text>
</xsl:otherwise>
</xsl:choose>
UPDATE: 9-18-2012 I tested the code you gave me, and my outer condition wasn't working... Also, I am using XSLT 2.0, so a for-each isn't necesssary.
New XML output that isn't QUITE working (too many ancestors), but I am getting them on only the correct p elements:
<section number="101">
<title style="I72">SEC. 101. SECTION TITLE.</title>
<p style="I20">(a)cpk2 In General.—Section 923...</p>
<p style="I20">(e)</p>
<p style="I22">(1)</p>
<p style="I24">  “I 101. (a) (e) (1) (A)cpk1 If the ... may—</p>
<p style="I26">(i)cpk2 if the violation is of a minor nature—</p>
</section>
XSLT code that is extremely close, and I "think" it is the that needs more work. I need to get the child enum element only from that first ancestor that has a belcode attribute, back down to enum that is the child of my text element's parent.
I'm thinking I need to replace the * in the value-of with something that gives me back the top ancestor I want, I'm just fairly new to XPath/XSLT, and fighting with the syntax.
<xsl:choose>
<xsl:when test="../@display-inline='yes-display-inline' and ancestor::*/@belcode[1]">
<xsl:value-of select="ancestor-or-self::*/enum"/>
<xsl:text>cpk1</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="../enum"/>
<xsl:text>cpk2</xsl:text>
</xsl:otherwise>
</xsl:choose>
Thanks in advance for any possible advice.
How do I go UP the tree from my subclause-text node (I promise I didn't name an element text), until I get to the ancestor that HAS a code, and DOESN'T have display-inline="yes-display-inline", and get ALL the child "enum"s inclusive? All the ancestor elements on the way also do NOT have either a header or text child, but do have an enum. (YES, there is an XML example).
Background:
I have nested XML input with section/subsection/paragraph/subparagraph/clause (each of which can also have an enum, header, text child) which gets flattened to output a section full of "p"s with a different style for what used to be sublevels, where the "enum", "header", "text" all get put into the "p".
Where I am having trouble is that in some cases, like my sample below, there is ONLY an enum for one or more levels. The output paragraph is supposed to get the code attr(transformed to style) of the FIRST level without "header" or "text", and all the "enum"s between that and the level that HAS the "text", which is where the "p" wrapper gets output, so that the flattening takes place appropriately. To put it in English, I need a (p style="P20")(e)(1)(A).
Nested XML Input:
<section code="P72">
<enum>101.</enum>
<header>SECTION TITLE.</header>
<subsection code="P20">
<enum>(e)</enum>
<paragraph display-inline="yes-display-inline">
<enum>(1)</enum>
<subparagraph display-inline="yes-display-inline">
<enum>(A)</enum>
<text>If the ... may—</text>
<clause belcode="I24">
<enum>(i)</enum>
<text>if the violation is of a minor nature—</text>
</clause>
</subparagraph>
</paragraph>
</subsection>
</section>
Desired output:
<section number="101">
<title style="I72">SEC. 101. SECTION TITLE.</title>
<p style="I20">(a) In General.—Section 923...</p>
<p style="I20">(e)(1)(A) If the ... may—</p>
<p style="I24">(i) if the violation is of a minor nature—</p>
</section>
Output I am getting:
<section number="101">
<title style="I72">SEC. 101. SECTION TITLE.</title>
<p style="I20">(a) In General.—Section 923...</p>
<p style="I20">(e)</p>
<p style="I22">(1)</p>
<p style="I24">(A) If the ... may—</p>
<p style="I26">(i) if the violation is of a minor nature—</p>
</section>
XSL Snippet that isn't working:
<xsl:template match="//subparagraph/text">
<p><xsl:attribute name="style"><xsl:value-of select="parent::subparagraph/@code"/></xsl:attribute>
<xsl:choose>
<xsl:when test="ancestor::*/enum and not(boolean(ancestor::*/header) or boolean(ancestor::*/text))"><xsl:value-of select="ancestor-or-self::*/enum"/><xsl:text> </xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="../enum"/><xsl:text> </xsl:text>
</xsl:otherwise>
</xsl:choose>
</p><xsl:text> </xsl:text>
</xsl:when>
</xsl:template>
I realize this is just the //subparagraph/text piece, but it is the part that needs to display the output enums, and I know how to STOP them displaying elsewhere, once I get them where I want them.