p2p.wrox.com Forums

p2p.wrox.com Forums (http://p2p.wrox.com/index.php)
-   XSLT (http://p2p.wrox.com/forumdisplay.php?f=86)
-   -   Converting XML to XML (making element mandatory) (http://p2p.wrox.com/showthread.php?t=41839)

boondocksaint20 April 27th, 2006 03:03 PM

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.


mhkay April 27th, 2006 04:53 PM

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

boondocksaint20 April 28th, 2006 08:17 AM

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.


mhkay April 28th, 2006 08:24 AM

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

boondocksaint20 April 28th, 2006 08:48 AM

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!


mhkay April 28th, 2006 08:58 AM

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

boondocksaint20 April 28th, 2006 10:01 AM

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?


mhkay April 28th, 2006 10:22 AM

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

boondocksaint20 April 28th, 2006 10:54 AM

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. :)


All times are GMT -4. The time now is 08:52 AM.

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