XML Plugin 1.0.1 released

We are proud to announce the immediate availability of the XML-Plugin version 1.0.1.

The plugin allows Servoy developers to create, manipulate and read XML documents directly from within Servoy. The plugin allows you for example to

  • Exchange data in a state-of-the-art format
  • Subscribe to RSS feeds
  • Display XML content in HTML without further coding (using a style sheet)
  • Directly archive Servoy records in XML format
  • Create MS Office (or OpenOffice) documents from templates (Office 2003 or greater)
  • Import FileMaker XML exported data
    Here is a (short) overview of the plugin’s classes and their functionality

XML-Plugin

  • create XMLDocument from file, URL, XML text, a Servoy record or foundset (possibly including relations)
  • create XMLElement using name or directly from a Servoy record
  • create XMLAttribute with name and value (optionally including namespace)
  • create XMLNamespace with prefix and URI
  • create RecordFormatter
    XMLDocument
  • get/set doctype
  • get/set encoding
  • add/get comments
  • add/get elements
  • add namespace declarations
  • get as (pretty formatted) text
  • get elements by XPath expression
  • get elements by their name
  • validate
  • write to file
  • transform using XSL
    XMLElement
  • get/set name
  • get/set text (value)
  • get/set namespace
  • add/get attributes
  • add/get/remove additional namespace declarations
  • add/get/remove children (optionally by name)
  • get descendants
    XMLAttribute
  • get/set name
  • get/set value
  • detach from parent
  • get parent

XMLNamespace

  • get/set prefix and URI
    RecordFormatter

The plugin can also be used to “archive” Servoy records (including related data) in XML format. If doing that, the data type has to be preserved, because after all XML is only text. You can create an XMLDocument directly from a Servoy record using a distinct format, that will include formatting information so data can be extracted using the original datatype. This is what the RecordFormatter does: convert a record to String and vice versa using formatting patterns. Here is an example that will write a complete foundset including all related data and reverse-create the record data with the original data type preserved with just a few calls:

// Creating an XML document from the foundset using all defined relations is a simple as
var vXml = plugins.XML.XMLDocument(foundset, allrelations);

// Now get the original data back out of the XML

// First, get the format used when converting data to text
var vFormatter = vXml.getFormatterElement();

// Now get all elements representing each record from the foundset
var vRecordElements = vXml.getRecordElements();

// Loop over all records found
for ( var i = 0 ; i < vRecordElements.length ; i++ )
{
	// Get an element representing record i from the foundset
	var vRecordElement = vRecordElements[i];
	// Get the record's data as object[columnName][data]
	var vRecordData = vRecordElement.getRecordData(vFormatter);
	// Get all relations found for this record as String[relationName][tableName]
	var vAllRelations = vRecordElement.getRelationsFromRecord();
	// Loop over all relations attached to this record
	for ( var j = 0 ; j < vAllRelations.length ; j++ )
	{
		// Get all record elements for relation j
		var vRelatedRecordElements = vRecordElement.getRecordsFromRelation(vAllRelations[j][0]);
		// Loop over all related records to get each single record for relation j
		for ( var k = 0 ; k < vRelatedRecordElements.length ; k++ )
		{
			// Get the related record's data as object[columnName][data]
			var vRelatedRecordData = vRelatedRecordElements[i].getRecordData(vFormatter);
		}
	}
}

The plugin can be found on www.servoy-plugins.de. You can buy a license from the shop or ask for a demo version (runs for 30 minutes after each start of Servoy) by sending a mail to plugins@maison-partner.de.

A preview of the XML file I want to read:

  <?xml version="1.0" encoding="UTF-8" ?> 
- <methodResponse>
  - <params>
    - <param>
      - <value>
        - <struct>
          - <member>
              <name>berichtobjectresultaat</name> 
             -<value>
               - <struct>
                 + <member>
                 + <member>

What is the best method to start at the collapsed tags.
Now I use var parents = vXml.getElements([“struct”]);, but in this result also the above is taken.
Is something like var parents = vXml.getElements([“params”, “param”, “value”, “struct”, “member”, “name”, “value”, “struct”, “member”]); possible, so i can directly take the right values?

The XML is not self-made, otherwise I wouldn’t use the same names in the whole thingy.

You could use XPATH expressions that allow you to query almost anything. Maybe a look at http://www.w3schools.com/xpath/ helps?

According to that link, I should use something like

var vStruct = vXml.getElements("params/param/value/struct/member/value/struct/member/value/struct/member");
var vtest = vStruct[0].getChildren("name");
application.output(vtest[0].text);

vStruct is empty, while I expect the child

Same when I change the order:

var vStruct = vXml.getElements("params");
var vtest = vStruct[0].getChildren("/param/value/struct/member/value/struct/member/value/struct/member/name");
application.output(vtest[0].text);

now vtest is empty

There should be a method called getElementsByXPath() that you have to use…

Heh heh,

So it wasn’t that wierd that it wouldn’t work in getElements…
Now it works! Thanx for help.

Also glad that we got rid of the trial version. Every time of testing I needed to restart, very anoying.

Also glad that we got rid of the trial version.

Me, too :lol:

Another dinner with your girlfriend tonight^^

Does it work the same with an XML string?

What I do is calling an method in a home made plugin. The plugin gives data back in XML. I load this XML data as a XMLdocument as following:

var test = globals.mediaField3;
var vXml = plugins.XML.XMLDocument(globals.mediaField3);
var vStruct = vXml.getElements("berichtobjectresultaat");

test is filled with xml code as show in the attachment
vXML gives root element not set, but no error.
vStruct gives root element not set error. (Java.lang.IllegalStateExeption)//

(rename the attachment to .xml, because the extension is not allowed)

test.txt (27.9 KB)

Nobody knows the problem I have with the XML.

I load a XML string in a parameter and try to read it. After that I can’t do anything with the XML structure.

Also tried other things, as beginning the xpath atthe first tag like:

% straatnaam = vXml.getElementByXPath("//SOAP-ENV:Envelope/SOAP-ENV:Body/ns1:kadasterEigendomsBerichtPerceelResponse/*")

Hoe can I create the XML from a record. Are there any required things to do?
This must be to simple(and goves only a xml header as result):

var record = foundset.getRecord(controller.getSelectedIndex());
var vXml = plugins.XML.XMLDocument(record); 
plugins.file.writeXMLFile("c:/test.xml",vXML);

Creating XML from records is really that simple. It is one of the nicest functions in the XML plugin, because you can use it for example to archive data. We create our own “grammar” for the XML document and take care of all the data type handling (blobs will be base64 encoded etc.). You can even provide a whole foundset and also very nice is the ability to provide relation names. The plugin will then automatically add related records to the XML without any extra coding from your side. So you could archive a whole foundset including related data with one call like this

var vAllRelations = new Array('customer_to_addresses', 'customer_to_orders, 'customers_to_phonenumbers');
var vXml = plugins.XML.XMLDocument(foundset, vAllRelations );

In your code, however, there is a mistake:

// this puts the record in a variable
var record = foundset.getRecord(controller.getSelectedIndex());
// this creates a XMLDocument object from that record
var vXml = plugins.XML.XMLDocument(record);
// this tries to write a String to a file, but vXML is a XMLDocument object and not a String
plugins.file.writeXMLFile("c:/test.xml",vXML);

What gets written in this case is the toString() representation of the XMLDocument object, which looks like this

[XMLDocument: No DOCTYPE declaration, Root is [XMLElement: <table/>]]

This is also what you see in the debugger when you look at the variable vXML. It is important that you realize that a XMLDocument is not XML (a text), but an object that allows you to do many things (add children, get elements and so on). You can’t add children to a text, because a text doesn’t know anything about “children”. A text knows stuff like length, upperCase etc.

What you should do is either

// Get the XML as String from the XMLDocument and write it
plugins.file.writeXMLFile("c:/test.xml",vXML.getAsText());

or even more straight forward

var vXml = plugins.XML.XMLDocument(foundset.getRecord(foundset.getSelectedIndex()));
vXml.writeToFile("d:/test.xml");

Optionally, you can provide a prettyFormat boolean that indents everything nicely and the encoding to writeToFile().

Hope this clears things.

Is it possible to add a single cell to the XML.

In my case: I make a complete XML from a foundset including relations for data. Then an url, to where the xml must be send is set in system settings.

I want to add this field (kinda manually) to the XML

Yes, of course. For example, you could simply call

vXml.addElement('url', 'http://www.servoy-plugins.de');
// where vXml is a XMLDocument

to add a “url” element underneath the root element (top level).

Which result do I get when I use an XSL in combination with an XML?

And is it possible to create an XML when I already have the XSL and the needed data?