Just Rudy
Just Rudy

Reputation: 700

Selecting specific elements that contain extra attributes

I'm fairly new to XSLT, and was wondering how I could replace certain elements. Basically, I would like to replace BR elements that come with extra attributes, with just a plain BR. The XML is as follows:

<outer_element>
    <p>
        <font face="Arial">
            Invitations<br>
        </font>
        <font face="Arial">
            Charts<br>
        </font>
    </p>
    <span style="font-size:12pt;">
        <br clear="all" style="font-size:18pt;">
    </span>
<outer_element>

And below is part of the XSL :

<xsl:template match="//outer_element">
    <xsl:element name="outer_element">
        <xsl:value-of select="."/>
    </xsl:element>
    <xsl:element name = "text">
        <xsl:value-of select="."/>
    </xsl:element>
</xsl:template>

Also, I don't know exactly whether it's a XSLT 1.0 or XSLT 2.0 solution that I am looking for.

Upvotes: 1

Views: 23

Answers (2)

Kirill Polishchuk
Kirill Polishchuk

Reputation: 56202

You can use this simple template:

<xsl:template match="br">
  <br/>
</xsl:template>

The complete template:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="@* | node()">
    <xsl:copy>
      <xsl:apply-templates select="@* | node()"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template match="br">
    <br/>
  </xsl:template>
</xsl:stylesheet>

Upvotes: 1

wwerner
wwerner

Reputation: 4327

Your input isn't valid XML/XHTML. The brs should be closed: <br/>. Also, the final end tag is also not a closing tag. If you are not expecting valid XHTML, have a look at https://jsoup.org/ or http://www.html-tidy.org/.

That out of the way: There is an XSLT pattern called identity transform that recursively copies the input to the output, but lets you override the copy process for each element you want.

The basic pattern locks like this.

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:template match="@*|node()">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
  </xsl:template>
</xsl:stylesheet>

Now add a template for br that copies only the element, not the attributes:

<xsl:template match="br">
 <xsl:copy/>
</xsl:template>

That should be it.

Upvotes: 1

Related Questions