I am attempting to move a node into it’s previous sibling’s child, and the fact that everything is on the same level is making it a little tricky for me.
Illustration of my input:
<dl>
<dlentry>
<dt> Title 1 </dt>
<dd> Title 1's definition </dd>
<dt> Title 2 </dt>
<dd> Title 2's definition </dd>
<dt> Title 3 </dt>
<dd> Title 3's definition </dd>
</dlentry>
</dl>
<p> part of title 3's definition </p>
<p> another part of title 3's definition </p>
What I am attempting to do is to take those 2 <p> elements at the bottom and concatenate their text to end of the last <dd> element’s text in <dlentry> because they are a part of that definition for “Title 3”.
Desired output:
<dl>
<dlentry>
<dt> Title 1 </dt>
<dd> Title 1's definition </dd>
<dt> Title 2 </dt>
<dd> Title 2's definition </dd>
<dt> Title 3 </dt>
<dd> Title 3's definition part of title 3's definition another part of title 3's definition </dd>
</dlentry>
</dl>
Another issue I’m dealing with is because of how bad the XHTML is in my source document, I need to do a regex match to on the text for those <p> elements to make sure it doesn’t hit anywhere else in the document.
I was able to successfully insert the first <p>‘s text as desired but am having trouble getting it to work in so I can do my regex match and also getting that 2nd
element’s text into the desired location as well.
Here is a code fragment from my stylesheet, using XSLT 2.0.
<xsl:analyze-string select="."
regex="my regex expression here">
<xsl:template match="dlentry">
<xsl:matching-substring>
<dlentry>
** <xsl:copy-of select="node()[ position() lt last()]"/>
<dd>
<xsl:copy-of select="node()[last()]/text()" />
<xsl:copy-of select=" parent::node()/following-sibling::node()[1]/text()"/>
</dd>
</dlentry>
</xsl:matching-substring>
<xsl:non-matching-substring>
<xsl:value-of select=".">
</xsl:non-matching-substring>
</xsl:template>
<xsl:template match="p[preceding-sibling::node()[1][self::node()[name(.)='dl']]]" />
<xsl:template match="p[preceding-sibling::node()[2][self::node()[name(.)='dl']]]" />
At the code line with the ** asterisks Saxon throws an error saying “Axis step child::node() cannont be used here: the context item is an atomic value.” I am not familiar with analyze-string but if I run my copy-of selects outside of analyze-string and just in a template, it runs fine.
Sorry that this question was kind of long but I wanted to share everything I had to this point.
Thanks in advance.
This short and simple XSLT 1.0 (and of course it is also XSLT 2.0):
when applied on the provided XML document:
produces the wanted, correct result: