Solved

How to strip out only the <p> tags that I want?

Posted on 2011-03-16
13
384 Views
Last Modified: 2013-11-18
See XML code below.
There could be any number of "Blank" <p> tags.
In the example, what I want to show on the page is ONLY this:


<p>This is a test program using the new template that gets the correct left-hand menu (a list of categories).</p>
<p>This would be a second paragraph.</p>

How can I do this in the xslt? (I'm fairly new with xslt). I thought I should be able to use an "apply-templates" on the "Teaser/p" tags and then in the template, only display the <p> tag if it is not blank and does not contain an image tag. But I can't quite figure out the right xpaths and syntax for the if tests.

For example, I had <xsl:apply-templates select="Teaser/p" />

Then I had a template that looks like this but it doesn't work ... actually, it only displays the image! (I'm really out of my league here)...

<xsl:template match="Teaser/p">
<xsl:if test=". != ''">
<p>
<xsl:copy-of select="." />
<p>
</xsl:template>
</xsl:template>

Thanks.




<Teaser>
    	<p>
<img src="/uploadedImages/CCA/Content/Forms/ADP_logo.gif" alt="ADP logo" title="ADP logo" />
      </p>
      <p> </p>
      <p>This is a test program using the new template that gets the correct left-hand menu (a list of categories).</p>
<p>This would be a second paragraph.</p>
<p>&#160;</p>
</Teaser>

Open in new window

0
Comment
Question by:alicia1234
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 6
  • 4
  • 2
  • +1
13 Comments
 
LVL 3

Expert Comment

by:KenTankrus
ID: 35148723
You should be able to open this in notepad (by rightclicking on it and go to "Open with" and if that option is not available, click "Chose program" and chose notepad) and use the find and replace function by going to "Edit" then "Replace".
0
 
LVL 18

Assisted Solution

by:zc2
zc2 earned 200 total points
ID: 35148749
Try something like the following:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" encoding="iso-8859-1"/>
	<xsl:template match="/Teaser">
		<xsl:for-each select="p[string-length(normalize-space(translate(.,'&#160;',''))) &gt; 0]">
			<xsl:copy-of select="." />
  		</xsl:for-each>
	</xsl:template>
</xsl:stylesheet>

Open in new window

0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 35148793
Try this

      <xsl:template match="Teaser/p[not(normalize-space(translate(., '&#160;', '')))][not(*)]"/>
      <xsl:template match="Teaser/p[normalize-space(translate(., '&#160;', '')) or *]">
            <xsl:copy-of select="." />
      </xsl:template>

The surprise comes from the fact that != does a set compare
0
Get 15 Days FREE Full-Featured Trial

Benefit from a mission critical IT monitoring with Monitis Premium or get it FREE for your entry level monitoring needs.
-Over 200,000 users
-More than 300,000 websites monitored
-Used in 197 countries
-Recommended by 98% of users

 
LVL 60

Expert Comment

by:Geert Bormans
ID: 35148869
to evaluate the differences of the solutions
- I don't understand what TenKantrus means, I assume he posted to the wrong question :-)
- my solution keeps the apply-templates approach you were using, you can simply replace your one template with my two templates. I also keep
- zc2's solution count on the fact that a Teaser can always only have p children and will drop the whitespace nodes between the p. zc2 will also drop the img only p.

Seems that you want to drop the image only p
I have included a new version taht also drops the image

I am by the way in favour of maintaining the original xsl:apply-templates approach, that is a better XSLT approach
<xsl:template match="Teaser/p[not(normalize-space(translate(., '&#160;', '')))]"/>
      <xsl:template match="Teaser/p[normalize-space(translate(., '&#160;', ''))]">
            <xsl:copy-of select="." />
      </xsl:template>

Open in new window

0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 35148897
Is your <xsl:apply-templates select="Teaser/p" />
in the right context?

you should get more than just the image
0
 
LVL 18

Expert Comment

by:zc2
ID: 35148964
Gertone,

Why you use the empty template for?
Isn't the result be the same without one?
0
 
LVL 60

Accepted Solution

by:
Geert Bormans earned 300 total points
ID: 35149091
well, it is a bit cleaner, it kills the text nodes in the whitespace only <p>
it also prevents them from being caught by a potential template for just "p" (less specific than "Teaser/p")
In the second version (the one that removes the img p as well, it prevents the <img> from being caught by a possible template for "img")

Since we only see a small portion of the stylesheet I like being specific

But I think it would even be nicer if we did it this way
<xsl:apply-templates select="Teaser/p[normalize-space(translate(., '&#160;', ''))]" />

and have this
     <xsl:template match="Teaser/p">
            <xsl:copy-of select="." />
      </xsl:template>

as an extra note
it is considered good practice to avoid xsl:if in settings like this in favour of predicates either in the template @match or in the @select of the apply-templates
0
 

Author Comment

by:alicia1234
ID: 35149183
Gertrone:
Could you explain to me what this is actually doing?

<xsl:apply-templates select="Teaser/p[normalize-space(translate(., '&#160;', ''))]" />

0
 

Author Comment

by:alicia1234
ID: 35149319
zc2 & Gertrone:

Each of your solutions produce the same result. They do display the text that I want. However - the two lines (see my original post) of text are to be two separate paragraphs, and they are not coming out that way. They are lumped together into a single <p> tag.

See: http://screencast.com/t/5Tw9B7MNCUNN
0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 35149327
Instead of selecting all Teaser/p elements,
you select all Teaser/p elements that have text in it

translate(., '&#160;', '') will replace the character 160 with nothing
normalize-space will drop the trailing and leading whitespace (and makes each sequence of white-space equal to one space)

normalize-space(translate(., '&#160;', '')) will turn every node that has only white-space in it into an empty string
[] puts a condition on the p
a string as a boolean expression will be true() unless it is empty

Teaser/p[normalize-space(translate(., '&#160;', ''))] selects all the Teaser/p elements that are not empty

0
 
LVL 60

Expert Comment

by:Geert Bormans
ID: 35149361
Well, something transforms your end-result into a png image, so it is hard for us to debug.
To my surprise I saw that you were duplicating the p tags in your earliest template.
Apparently you have a process in place that removes one level of <p> further down the road

Either find out what that process is, or duplicate the <p> again
<xsl:template match="Teaser/p">
        <p>
            <xsl:copy-of select="." />
        <p>
      </xsl:template>
0
 

Author Comment

by:alicia1234
ID: 35149384
Never mind my comment about it not separating out the <p> tags. During my testing I had inserted another xml tag into the html to try out something different. When I got that out of the way, both of your solutions worked.

Points to both of you because zc2 was first with a solution that would work, but Gertrone gave what seems to be "better" solution and lots of explanation.

0
 

Author Comment

by:alicia1234
ID: 35149401
Sorry about that ... I do have other xsl that displays the image separately, that's why you see it.
I needed to format the image separately instead of displaying it in context with the original html.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Preface This article introduces an authentication and authorization system for a website.  It is understood by the author and the project contributors that there is no such thing as a "one size fits all" system.  That being said, there is a certa…
Preface In the first article: A Better Website Login System (http://www.experts-exchange.com/A_2902.html) I introduced the EE Collaborative Login System and its intended purpose. In this article I will discuss some of the design consideratio…
The viewer will the learn the benefit of plain text editors and code an HTML5 based template for use in further tutorials.
The viewer will learn how to create a basic form using some HTML5 and PHP for later processing. Set up your basic HTML file. Open your form tag and set the method and action attributes.: (CODE) Set up your first few inputs one for the name and …

691 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question