Xsl filter on select
I would like to select all descendant streams but "blog". For example, only a subtree should appear in the output. I am trying this xsl code:
<xsl:template match="rdf:RDF">
<xsl:copy>
<xsl:copy-of select="descendant::*[not(descendant::blog)]"/>
</xsl:copy>
</xsl:template>
for this xml:
<rdf:RDF>
<profesor rdf:ID="profesor_39">
<nombre rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
>Augusto</nombre>
</profesor>
<blog rdf:ID="blog_41">
<entradas>
<entrada_blog rdf:ID="entrada_blog_42">
<etiquetas>
<tecnologia rdf:ID="tecnologia_49">
<termino rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
>Atom</termino>
</tecnologia>
</etiquetas>
<autor>
<alumno rdf:ID="alumno_38">
<nombre rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
>Jesus</nombre>
</alumno>
</autor>
</entrada_blog>
</entradas>
<autores rdf:resource="#alumno_38"/>
<direccion rdf:datatype="http://www.w3.org/2001/XMLSchema#string"
>http://tfg1.unex.es/10comunidad/wordpress/</direccion>
</blog>
</rdf:RDF>
What am I missing? Blog nodes are still printing on output. Thanks.
Omit blog and all its children:
<xsl:template match="RDF">
<xsl:copy-of select="child::node()[name() != 'blog']"/>
</xsl:template>
To omit the blog, but still o / p its children:
<xsl:template match="RDF">
<xsl:copy-of select="descendant::node()[name() != 'blog']"/>
</xsl:template>
a source to share
Here's the complete solution:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<!-- By default, recursively copy all nodes unchanged -->
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<!-- But strip out <blog> -->
<xsl:template match="blog"/>
<!-- If you want to strip out just the <blog> start and end tags, use this instead:
<xsl:template match="blog">
<xsl:apply-templates/>
</xsl:template>
-->
</xsl:stylesheet>
a source to share
The not (descendant :: blog) clause excludes any node that has a descendant named "blog".
So, if you have:
<blog id="1">
<test id="1.1">
<blog id="1.1.1" />
</test>
</blog>
<blog id="2">
<test id="2.1" />
</blog>
It will exclude <blog id = "1"> and <test id = "1.1"> because these nodes have <blog id = "1.1.1"> as a child.
But this does not rule out <blog id = "1.1.1"> or <blog id = "2"> because they have no descendants named "blog"
Also note that your choice of descendant :: * [not (descendant :: blog)] will print <test id = "2.1"> twice: once inside <blog id = "2">, and again on its own.
For a complete solution, the one suggested by Evan Lenz (identity transformation with empty redefinition pattern for "block" nodes) is probably the one that gives the desired result.
a source to share