Wrox Programmer Forums

Need to download code?

View our list of code downloads.

Go Back   Wrox Programmer Forums > XML > XSLT
Password Reminder
Register
Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read
XSLT General questions and answers about XSLT. For issues strictly specific to the book XSLT 1.1 Programmers Reference, please post to that forum instead.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the XSLT section of the Wrox Programmer to Programmer discussions. This is a community of tens of thousands of software programmers and website developers including Wrox book authors and readers. As a guest, you can read any forum posting. By joining today you can post your own programming questions, respond to other developersí questions, and eliminate the ads that are displayed to guests. Registration is fast, simple and absolutely free .
DRM-free e-books 300x50
Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old April 27th, 2006, 03:03 PM
Authorized User
 
Join Date: Apr 2006
Location: , , .
Posts: 11
Thanks: 0
Thanked 0 Times in 0 Posts
Default Converting XML to XML (making element mandatory)

Hi,

I have an XML that I am pulling from a webservice. The webservice schema specifies that certain fields have a minoccurs of zero, so obviously the document does not list elements in sequence that have nulls.

This is a problem because my vb.net application that I wrote will immediate call another function that will read the XML and write it to a Sql Server database, and the function crashes bc the document does not contain elements with nulls (because if element #2 has a null in one record, it doesn't write it to the xml so my program thinks element #3 is element #2).

Can you use XSLT to specify either to always write an element no matter what or to write it and put 'null' as a value if it is 'null' is the byte stream from the Web Service?

Thanks in advance.

Reply With Quote
  #2 (permalink)  
Old April 27th, 2006, 04:53 PM
mhkay's Avatar
Wrox Author
Points: 18,410, Level: 59
Points: 18,410, Level: 59 Points: 18,410, Level: 59 Points: 18,410, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,949
Thanks: 0
Thanked 289 Times in 284 Posts
Default

It's dangerous to talk of "nulls" - there's no such thing in XML. You simply mean an absent element.

In XSLT, if you want to replace absent elements by empty elements, you can write something like this:

<xsl:template match="person">
  <name>
    <xsl:value-of select="name"/>
  </name>
  <age>
    <xsl:value-of select="age"/>
  </age>

etc.

If you want to be more clever you could probably make it table-driven.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #3 (permalink)  
Old April 28th, 2006, 08:17 AM
Authorized User
 
Join Date: Apr 2006
Location: , , .
Posts: 11
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Will this work for elements that may be there some of the time, but won't the rest of the time? The element in question exists in about half of the records.

Reply With Quote
  #4 (permalink)  
Old April 28th, 2006, 08:24 AM
mhkay's Avatar
Wrox Author
Points: 18,410, Level: 59
Points: 18,410, Level: 59 Points: 18,410, Level: 59 Points: 18,410, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,949
Thanks: 0
Thanked 289 Times in 284 Posts
Default

The code:

  <name>
    <xsl:value-of select="name"/>
  </name>

creates a copy of the input <name> element if there is one (assuming its content is text only), and creates a new empty <name/> element otherwise. That was my reading of your requirements. If the text-only assumption isn't valid, it would be better to do:

  <name>
    <xsl:apply-templates select="name/node()"/>
  </name>

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #5 (permalink)  
Old April 28th, 2006, 08:48 AM
Authorized User
 
Join Date: Apr 2006
Location: , , .
Posts: 11
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Ok, I've got a test setup, but I can't get the result I want. It outputs '121', and I did a View Source, and the XML still looks the same. I need the XML to look like this:

This is my desired results:

<testXML>
  <name>
    <test1>1</test1>
    <test2>2</test2>
  </name>
  <name>
    <test1>1</test1>
    <test2></test2> //line that needs to appear
  </name>
</testXML>
-----------------------

Using this code:

My XSL:
------------------------------------------
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

   <xsl:template match="name">
    <test1>
        <xsl:value-of select="test1"/>
    </test1>
    <test2>
        <xsl:value-of select="test2"/>
    </test2>
   </xsl:template>

</xsl:stylesheet>
------------------------

My XML:
-----------------------

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>

<testXML>
  <name>
    <test1>1</test1>
    <test2>2</test2>
  </name>
  <name>
    <test1>1</test1>
  </name>
</testXML>


Thanks again for your help!

Reply With Quote
  #6 (permalink)  
Old April 28th, 2006, 08:58 AM
mhkay's Avatar
Wrox Author
Points: 18,410, Level: 59
Points: 18,410, Level: 59 Points: 18,410, Level: 59 Points: 18,410, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,949
Thanks: 0
Thanked 289 Times in 284 Posts
Default

Sounds as if you're running in the browser. That's the worst way to develop and debug XSLT code - you can't see what you're doing, and the diagnostics are very poor. Either use an XML IDE such as Stylus Studio or XML Spy, or use a plain old text editor and command line (I'm using jEdit and Saxon to develop some complex stylesheets for a client today, and it works fine).

121 is the string value of both the old and the new XML, so this doesn't tell you anything. View Source does what it says - it shows you the source. If you're in IE, there's a plug-in you can get to view the result - but I don't recall the details, as it's not the way I prefer to develop.

Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #7 (permalink)  
Old April 28th, 2006, 10:01 AM
Authorized User
 
Join Date: Apr 2006
Location: , , .
Posts: 11
Thanks: 0
Thanked 0 Times in 0 Posts
Default

Hi mhkay,

I opened the xml is XMLSPY and did a View -> TextView and the results are:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<testXML>
    <name>
        <test1>1</test1>
        <test2>2</test2>
    </name>
    <name>
        <test1>1</test1>
    </name>
</testXML>

I need them to look like this:

<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="test.xsl"?>
<testXML>
    <name>
        <test1>1</test1>
        <test2>2</test2>
    </name>
    <name>
        <test1>1</test1>
                <test2></test2>
    </name>
</testXML>

Am I missing something?

Reply With Quote
  #8 (permalink)  
Old April 28th, 2006, 10:22 AM
mhkay's Avatar
Wrox Author
Points: 18,410, Level: 59
Points: 18,410, Level: 59 Points: 18,410, Level: 59 Points: 18,410, Level: 59
Activity: 0%
Activity: 0% Activity: 0% Activity: 0%
 
Join Date: Apr 2004
Location: Reading, Berks, United Kingdom.
Posts: 4,949
Thanks: 0
Thanked 289 Times in 284 Posts
Default

In fact the stylesheet isn't correct, because it isn't outputting a name element. It should be

<xsl:template match="name">
<name>
    <test1>
        <xsl:value-of select="test1"/>
    </test1>
    <test2>
        <xsl:value-of select="test2"/>
    </test2>
</name>
</xsl:template>

But that doesn't account for your output. You seem to be doing something badly wrong (in fact, you seem to be looking at the input).

With the above change, Saxon outputs

<?xml version="1.0" encoding="UTF-8"?>
  <name><test1>1</test1><test2>2</test2></name>
  <name><test1>1</test1><test2/></name>

(if you want it indented, add <xsl:output indent="yes"/>)


Michael Kay
http://www.saxonica.com/
Author, XSLT Programmer's Reference and XPath 2.0 Programmer's Reference
Reply With Quote
  #9 (permalink)  
Old April 28th, 2006, 10:54 AM
Authorized User
 
Join Date: Apr 2006
Location: , , .
Posts: 11
Thanks: 0
Thanked 0 Times in 0 Posts
Default

That worked!††

I just have one last question real quick:
Is there a way to set a default value for elements, if per se they have no value, like the <test2></test2>, could you set it to <test2>null</test2>?††

Thanks again for your help. :)
Reply With Quote
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are Off

Similar Threads
Thread Thread Starter Forum Replies Last Post
Difficulties converting XML to XML using XSLT Reznik XSLT 7 June 3rd, 2008 05:45 AM
Help in making a FLAT xml to a structured xml shlomi XSLT 0 July 19th, 2007 07:58 AM
Converting Source Xml into Target Xml Using XSL. alapati.sasi XSLT 3 May 14th, 2007 10:54 AM
converting an xml to another xml sreeUS XSLT 4 May 2nd, 2006 01:59 PM
Help making a doc using XML topshed XML 2 January 28th, 2006 07:05 PM



All times are GMT -4. The time now is 02:25 AM.


Powered by vBulletin®
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
© 2013 John Wiley & Sons, Inc.