Remove some
tags from XML weather feed

2019-08-20 11:20发布

I'm trying to format a weather feed on my site via an RSS XML, which is easily acheived. The trouble is that it renders cascading down the page, and I want to have it running across the page.

From what I can gather, it looks as though I need to get rid of the <br /><br /> tags so they will align next to each other.

The XML source looks like this:

<description>
    <![CDATA[ <b>Wednesday</b>
    <br />
    <img src="/images/icons/fcast_30/mostly_cloudy.gif">
    <br /> Mostly cloudy<br /> -1&#176;C - 14&#176;C
    <br /><br />
    <b>Thursday</b>
    <br />
    <img src="/icons/fcast_30/frost_then_sunny.gif">
    <br /> Frost then sunny<br /> 1&#176;C - 13&#176;C
    <br /><br />
    <b>Friday</b>
    <br />
    <img src="/images/icons/fcast_30/rain.gif">
    <br /> Rain<br /> 2&#176;C - 11&#176;C
    <br /><br />
    <b>Saturday</b>
    <br />
    <img src="/images/icons/fcast_30/clearing_shower.gif">
    <br /> Clearing shower<br /> 0&#176;C - 12&#176;C
    <br /><br /> ]]>
</description>

My output XSL code look a little like this:

<xsl:for-each select="rss/channel">
    <xsl:value-of select="(item/title)[2]"/>
    <xsl:value-of select="substring((item/description)[1],30,15)" disable-output-escaping="yes"/>
    <xsl:value-of select="(item/description)[2]" disable-output-escaping="yes"/>
</xsl:for-each>

And the output renders to look like this:

Wednesday
IMG.gif
Mostly cloudy
-1°C - 14°C

Thursday
IMG.gif
Frost then sunny
1°C - 13°C

Friday
IMG.gif
Rain
2°C - 11°C

Saturday
IMG.gif
Clearing shower
0°C - 12°C

How would I go about removing the <br /><br /> tags after each day so they align next to each other, but leaving the other singular <br> tags?

标签: html xslt rss tags
2条回答
smile是对你的礼貌
2楼-- · 2019-08-20 12:16

As already noted by others, the wanted transformation is impossible, unless the CDATA section (that makes the markup just regular, plain, one-dimensional text) is removed.


This complete transformation:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

 <xsl:template match=
 "br[preceding-sibling::node()
       [self::* or self::text()[normalize-space()]
        ][1]
        [self::br]
    or
     following-sibling::node()
       [self::* or self::text()[normalize-space()]
        ][1]
        [self::br]
    ]"/>
</xsl:stylesheet>

when applied on the XML document obtained after removing the CDATA section and correcting numerous malformedness errors:

<description>
        <b>Wednesday</b>
        <br />
        <img src="/images/icons/fcast_30/mostly_cloudy.gif"/>
        <br /> Mostly cloudy<br /> -1&#176;C - 14&#176;C
        <br /><br />
        <b>Thursday</b>
        <br />
        <img src="/icons/fcast_30/frost_then_sunny.gif"/>
        <br /> Frost then sunny<br /> 1&#176;C - 13&#176;C
        <br /><br />
        <b>Friday</b>
        <br />
        <img src="/images/icons/fcast_30/rain.gif"/>
        <br /> Rain<br /> 2&#176;C - 11&#176;C
        <br /><br />
        <b>Saturday</b>
        <br />
        <img src="/images/icons/fcast_30/clearing_shower.gif"/>
        <br /> Clearing shower<br /> 0&#176;C - 12&#176;C
        <br /><br />
</description>

produces the wanted, correct result:

<description>
   <b>Wednesday</b>
   <br/>
   <img src="/images/icons/fcast_30/mostly_cloudy.gif"/>
   <br/> Mostly cloudy<br/> -1°C - 14°C
            <b>Thursday</b>
   <br/>
   <img src="/icons/fcast_30/frost_then_sunny.gif"/>
   <br/> Frost then sunny<br/> 1°C - 13°C
            <b>Friday</b>
   <br/>
   <img src="/images/icons/fcast_30/rain.gif"/>
   <br/> Rain<br/> 2°C - 11°C
            <b>Saturday</b>
   <br/>
   <img src="/images/icons/fcast_30/clearing_shower.gif"/>
   <br/> Clearing shower<br/> 0°C - 12°C
            </description>

Explanation:

  1. The identity rule copies "as-is" every matched node, for which it is selected for execution.

  2. There is a single template overriding the identity template. It matches any br whose first sibling (either preceding-sibling or following-sibling) that isn't a whitespace-only text node, is also a br.

  3. This overriding template has empty body, which effectively "deletes" any matched br element from the output.

查看更多
乱世女痞
3楼-- · 2019-08-20 12:16

First of all, DON'T put XML inside a CDATA section unless you are forced to do so by other parties.

Assuming that you have moved the XML content to outside of a CDATA section, apply an XSLT style-sheet with the identity transform and this template ....

<xsl:template match="br[
  preceding-sibling::node()[self::br] |
  following-sibling::node()[self::br] ]" />

This template will remove adjacent <br> elements. If there is any text between the two <br>s, even just white space, the <br>s will not get removed.


Note

This solution is wrong. See Dimitre's answer.

查看更多
登录 后发表回答