Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations biv343 on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Simple XSLT Question

Status
Not open for further replies.

Wickersty

Programmer
Nov 13, 2002
51
US
Sorry to ask this. I'm new at creating XSLT's, and I just want to get this simple task to work. :) I've rewritten my "XML" and "XSLT" in really dumbed down, simple structure below. My Question follows...

Here's my XML:

<examview>
<question>
<text>
This is a question.
<data>19903</data>
</text>
</question>
</examview>

Here is my XSLT:

<xsl:template match=&quot;examview&quot;>
<html>
<body>

<xsl:apply-templates/>

</body>
</html>
</xsl:template>

<xsl:template match=&quot;question&quot;>
<xsl:value-of select=&quot;text&quot;/>
</xsl:template>

Here is my Question:

Upon output, I get:

&quot;This is a question.19903&quot;

How do I get it so that only &quot;This is a question.&quot; will be output, and the information within <data> (&quot;19903&quot;) does not get output?

Thanks, and I know this is a complete newb question - but I just want to get on the right track here.

Jeff
 
Don't nest the tags, Use:

Code:
<examview>
     <question>
          <text>
          This is a question.
          </text>
          <data>19903</data>
     </question>
</examview>

Instead.
 
What if it's too late. I've got a bunch of XML files that set the tags up like that... with:

<question>
<text>
This is the question.
<data>Some Data</data>
</text>
</question>

I don't really have the option of changing them so they are not nested. Is it impossible to display the contents of <text> but not the contents of <data> as I have it now?

Jeff
 
USe the substring-before() function to return the part of the value before the <data>:
[tt]
<xsl:template match=&quot;examview&quot;>
<html>
<body>

<xsl:apply-templates/>

</body>
</html>
</xsl:template>

<xsl:template match=&quot;question&quot;>
<xsl:value-of select=&quot;substring-before(text,text/data)&quot;/>
</xsl:template>
[/tt]
 
That sounds like it would do it - however, it doesn't work as entered. Says: &quot;Keyword xsl:variable may not be used in namespace&quot;

Are you sure its okay as is? I went online and did some research into the substring-before function. However, all the sites just say what it does and don't show it in an example.

I feel like I'm so close, but can't quite get it working.

Thanks for all the help folks,

JEff
 
Here's What I have -

XML File:
Code:
<?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?>
<?xml-stylesheet type=&quot;text/xsl&quot; href=&quot;examqn.xsl&quot;?>
<examview>
     <question>
          <text>
          This is a question.
          <data>19903</data>
          </text>
     </question>
</examview>

XSL File:
Code:
<?xml version=&quot;1.0&quot; encoding=&quot;ISO-8859-1&quot;?>
<xsl:stylesheet version=&quot;1.0&quot;
xmlns:xsl=&quot;[URL unfurl="true"]http://www.w3.org/1999/XSL/Transform&quot;>[/URL]
<xsl:template match=&quot;examview&quot;>
     <html>
     <body>

     <xsl:apply-templates/>

     </body>
     </html>
</xsl:template>

<xsl:template match=&quot;question&quot;>
     <xsl:value-of select=&quot;substring-before(text,text/data)&quot;/>
    
</xsl:template>

</xsl:stylesheet>

Works for me (IE 6, Win2K)
 
OK. Great. That does work! Thank you.

One more question, if I may:

Your solution works if all of my <question> tags have a <data> tag within it. However, if only SOME of my <question> tags have <data> tags, and others don't, what happens is those <question> tags that DO HAVE <data> tags display properly (that is, the <question> content is displayed but not the <data> content.) However, for those <question> tags that DO NOT have <data> tags within them, nothing at all is displayed.

Picture this XML, to get a better idea:

<examview>
<question>
<text>
This is a question.
<data>19903</data>
</text>
</question>
<question>
<text>
This is a question.
</text>
</question>
</examview>

The output I get is: &quot;This is a question.&quot; In other words, the first one is outputted, but the second one isn't (because there's no <data> tags within the <text> tags. Is there some way to use an &quot;if&quot; function to see IF there is a data tag, and if there IS one, use the substring-before fuction? But if there isnt one, just to use a regular <xsl:value-of select=&quot;text&quot;> statement?

Thanks for all your help.

Jeff

 
UPDATE: I've read that the <xsl:if> function really doesn't do IF-ELSE. However, there's an <xsl:choose> function that might simulate IF-ELSE, or there's an contains(baseString,substring) function that may check to see if the <text> contains the <data>.

But - Im having trouble figuring out how these would work.

Thanks,

Jeff
 
<xsl:template match=&quot;question&quot;>
<xsl:apply-templates select=&quot;text() |* [not(self::data)]&quot;/>
</xsl:template>
 
Awesome! Took a litte tweaking to find the right XPath (my &quot;real&quot; XML doc is a bit more complex than the dummy one I provided in this thread), but this did it. Thanks SO much muligh! I really appreciate it.

Now - let me ask you one final question:

Let's say that: <xsl:apply-templates select=&quot;text() |* [not(self::data)]&quot;/>

returns no output at all... for instance, the XML code was:

<question>
<text>
<data>This is some data.</data>
</text>
</question>

The result of a <xsl:apply-templates select=&quot;text() |* [not(self::data)]&quot;/> would be NOTHING.

Is there a way I can use an <xsl:if> tag to determine if no output is made, and if so, provide some text. I.E., if, in the above example, nothing gets outputted, I would want my XSLT to display: &quot;There is no TEXT available.&quot;

Thanks again,

Jeff
 
Yeah, sorry the code I gave you needed to be tweaked. I think the following should work for you.

<?xml version=&quot;1.0&quot;?>
<xsl:stylesheet xmlns:xsl=&quot; version=&quot;1.0&quot;>
<xsl:eek:utput method=&quot;html&quot;/>
<xsl:strip-space elements=&quot;*&quot;/>
<xsl:template match=&quot;examview&quot;>
<html>
<body>

<xsl:apply-templates/>

</body>
</html>
</xsl:template>

<xsl:template match=&quot;question&quot;>
<xsl:choose>
<xsl:when test=&quot;string-length(text) != string-length(text/data)&quot;>
<xsl:for-each select=&quot;text&quot;>
<xsl:apply-templates select=&quot;text() | *[not(self::data)]&quot;/>
</xsl:for-each>
</xsl:when>
<xsl:eek:therwise>
<xsl:text>There is no text data</xsl:text>
</xsl:eek:therwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
 
Worked like a charm. Many thanks for your efforts, folks - especially mulligh. I couldn't have done it without your help. Extremely helpful thread, and I appreciate your help.

Jeff
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top