Reputation: 159
I have the following XML code:
<detaileddescription>
<para>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum aliquam
interdum erat, <computeroutput>monospace output</computeroutput> eget rhoncus nunc
porttitor ut. Ut ac metus sed erat rutrum dignissim.
<parameterlist kind="param">
<parameteritem>
<parameternamelist>
<parametername>item1</parametername>
</parameternamelist>
<parameterdescription>
<para>Param description.</para>
</parameterdescription>
</parameteritem>
</parameterlist>
<simplesect kind="return">
<para>
<computeroutput>ERR</computeroutput> mattis nunc sed velit ultricies
volutpat. Suspendisse potenti. Vivamus nec ligula blandit urna lobortis
tempus.
</para>
</simplesect>
</para>
</detaileddescription>
I'd like to use xsl:apply-templates only to the text node child of the detaileddescription/para
element and the <computeroutput>
element that's inside the text node. In other words, I want to apply-templates only to the following content:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum aliquam
interdum erat, <computeroutput>monospace output</computeroutput> eget rhoncus nunc
porttitor ut. Ut ac metus sed erat rutrum dignissim.
Can anyone show me how to do this using XSLT 2.0 and XPath 2.0?
Upvotes: 3
Views: 3295
Reputation: 243569
This transformation:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:apply-templates select="*/para[1]/(text()|computeroutput)"/>
</xsl:template>
<xsl:template match="computeroutput">
<xsl:sequence select="."/>
</xsl:template>
</xsl:stylesheet>
when applied on the provided XML document:
<detaileddescription>
<para>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum aliquam
interdum erat, <computeroutput>monospace output</computeroutput> eget rhoncus nunc
porttitor ut. Ut ac metus sed erat rutrum dignissim.
<parameterlist kind="param">
<parameteritem>
<parameternamelist>
<parametername>item1</parametername>
</parameternamelist>
<parameterdescription>
<para>Param description.</para>
</parameterdescription>
</parameteritem>
</parameterlist>
<simplesect kind="return">
<para>
<computeroutput>ERR</computeroutput> mattis nunc sed velit ultricies
volutpat. Suspendisse potenti. Vivamus nec ligula blandit urna lobortis
tempus.
</para>
</simplesect>
</para>
</detaileddescription>
processes (applies templates to) only the wanted nodes and for this demo puposes just copies these nodes to the output:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum aliquam
interdum erat, <computeroutput>monospace output</computeroutput> eget rhoncus nunc
porttitor ut. Ut ac metus sed erat rutrum dignissim.
Upvotes: 1
Reputation: 310
If I understand your question correctly, this should work:
<xsl:apply-templates select="detaileddescription/para/(text()|computeroutput)"/>
of course, depending on the context note. Otherwise, you could also mean the corresponding tempate that will fit only those elements you want:
<xsl:template match="detaileddescription/para/(text()|computeroutput)"/>
<xsl:copy-of select="." />
<!-- or whatever you want to do with it -->
</xsl:template>
Hope this helps, R
Upvotes: 2
Reputation: 6825
here is one, although probably not the best way to do it. i baked you a cake
i created a copy-template, which copies everything and the last two templates are stop-templates, that don't produce any output.
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="detaileddescription">
<xsl:apply-templates select="para"/>
</xsl:template>
<xsl:template match="para">
<xsl:apply-templates select="@*|node()"/>
</xsl:template>
<xsl:template match="parameterlist"/>
<xsl:template match="simplesect"/>
i edited in the second template: this will remove (or rather not copy) the <detaileddescription>
tag.
Upvotes: 2