34

At runtime I can have two formats of a XML file:

  1. <root>
        <diagram> 
            <graph color= "#ff00ff">    
                <xaxis>1 2 3 12 312 3123 1231 23 </xaxis>
                <yaxis>1 2 3 12 312 3123 1231 23 </yaxis>
            </graph>  
        </diagram> 
    </root>
    
  2. <root>
        <diagram> 
            <graph>    
                <xaxis>1 2 3 12 312 3123 1231 23 </xaxis>
                <yaxis>1 2 3 12 312 3123 1231 23 </yaxis>
            </graph>  
        </diagram> 
    </root>
    

Depending on the presence of the color attribute i have to process the values of the xaxis and yaxis.

I need to do this using XSL. Can anyone help me in hinting me a snippet where i can check these condtions.

I tried using

<xsl: when test="graph[1]/@color">
     //some processing here using graph[1]/@color values
</xsl:when>

i got an error ...

4
  • Did you use the xsl:choose :: (xsl:when+|xsl:otherwise) instruction? Commented Nov 10, 2010 at 16:37
  • Yes i used the xsl:choose ...xsl:when+xsl:otherwise conditions in vain.. Commented Nov 10, 2010 at 16:41
  • And what is the context node? / document root, root element, diagram element, graph element...? Commented Nov 10, 2010 at 20:54
  • Good question, +1. See my answer for a simple solution that uses to the maximum such powerful features as XSLT pattern matching and push style processing. :) Commented Nov 11, 2010 at 3:18

4 Answers 4

37

Here is a very simple way to do conditional processing using the full power of XSLT pattern matching and exclusively "push" style, and this even avoids the need to use conditional instructions such as <xsl:if> or <xsl:choose>:

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

 <xsl:template match="/root/diagram[graph[1]/@color]">
  Graph[1] has color
 </xsl:template>

 <xsl:template match="/root/diagram[not(graph[1]/@color)]">
  Graph[1] has not color
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied on the following XML document:

<root>
    <diagram>
        <graph color= "#ff00ff">
            <xaxis>1 2 3 12 312 3123 1231 23 </xaxis>
            <yaxis>1 2 3 12 312 3123 1231 23 </yaxis>
        </graph>
        <graph>
            <xaxis>101 102 103 1012 10312 103123 101231 1023 </xaxis>
            <yaxis>101 102 103 1012 10312 103123 101231 1023 </yaxis>
        </graph>
    </diagram>
</root>

the wanted, correct result is produced:

  Graph[1] has color

when the same transformation is applied on this XML document:

<root>
    <diagram>
        <graph>
            <xaxis>101 102 103 1012 10312 103123 101231 1023 </xaxis>
            <yaxis>101 102 103 1012 10312 103123 101231 1023 </yaxis>
        </graph>
        <graph color= "#ff00ff">
            <xaxis>1 2 3 12 312 3123 1231 23 </xaxis>
            <yaxis>1 2 3 12 312 3123 1231 23 </yaxis>
        </graph>
    </diagram>
</root>

again the wanted and correct result is produced:

  Graph[1] has not color

One can customize this solution and put whatever code is necessary inside the first template and if necessary, inside the second template.

Sign up to request clarification or add additional context in comments.

4 Comments

@Dimitre Novatchev Is it possible to to use this solution into <apply-template> instructions? I'm generating code from XML with XSLT, and I would like to filter some getter and setter ?
@chepseskaf: If you mean is it possible to use the predicates in the select attribute of xsl:apply-templates instead of having them in the match patterns, the answer is positive, but doing so isn't necessary and leads to a more "push" or imperative style of processing, which decreases simplicity, understandability, maintainability and optimizability.
Sad to see this interesting question with no selected answer although it's 10 yrs old. But I think what the OP wants was <xsl:template match="/root/diagram/graph[@color]"> and <xsl:template match="/root/diagram/graph[not(@color)]">, to process all graph nodes in fact.
@Fuujuhi, Maybe you are right, but in the SO environment "all guesses are equal". Here the OP doesn't reveal his purpose -- only that he had a problem with conditional processing. This answer shows one good solution to the problem, without trying to guess deeper.
24

Customize the template in one match like this

<xsl:template match="diagram/graph">
  <xsl:choose>
    <xsl:when test="@color">
         Do the Task
    </xsl:when>
    <xsl:otherwise>
         Do the Task
    </xsl:otherwise>
  </xsl:choose>
</xsl:template>**

Comments

4
<xsl:when test="graph[1]/@color">
     //some processing here using graph[1]/@color values
</xsl:when>

I'm going to make a guess here since your question is missing a lot of important information, such as the context in which thie <xsl:when... appears. If your comment is correct, what you want to do is process graph[1]/xaxis and .../yaxis, not graph[1]/@color values.

2 Comments

Yes. For ex. based on the existence of the attribute "color" i need to set some variable say..graph-color. Now i want a simple if-else statement based on whether the attribute is present or not. If true..then i may set a variable as contained in the attribute.Else i may use a default color
Please edit your post to include more of your stylesheet so we can figure out what you're trying to accomplish.
1

I don't get it - apart from some slight syntax tweak towards using apply-templates:

<xsl:template match="graph[1][@color]">
  <!-- your processing here -->
</xsl:template>

There's not much we can tell you without knowing what you actually want to do.

5 Comments

i just want to process the graph based on the presence of the attribute "color" in the xml file...
its like if(attribute is present?) process 1; else process 2;
Also this graph[1][@color] doesnt recognise the attribute presence
Yes it does. If there's no color attribute on the graph element, that template won't be selected.
Yes thats the point. There may be or may not be a "color" attribute in that XML file and the XSL has to check whether there is one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.