axl main logo
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Modules Pages
axl_bool axl_ns_doc_validate ( axlDoc doc,
axlError **  error 
)

Allows to check XML 1.0 namespace rules for the document loaded.

XML 1.0 Namespaces definition allows you to define documents that are resistent to tag clashing, making your product to be more usable at any level, being mixed with other products.

This function allows you to check a xml document, already loaded with the Axl Doc base API (axl_doc_parse_from_file, axl_doc_parse or axl_doc_create), if it follows the namespaces contrains (XML 1.0 Namespaces http://www.w3.org/TR/REC-xml-names/).

The idea behind this function is to ensure that the document has the proper XML 1.0 Namespace declarations, which will be used by the following function to help you detect those tags recognized by your XML software, ensuring this matching is done inside your namespace:

Here is a simple example on how to load a xml document, add namespace checking support, and read content inside without compromissing your code to node tag collitions:

/* include support from the base library */
#include <axl.h>
/* include support for ns */
#include <axl_ns.h>
/* declare our namespace */
#define HTML_NS "http://www.w3.org/1999/xhtml"
int main (int argc, char ** argv)
{
axlDoc * doc;
axlNode * node;
axlError * error;
/* init axl library */
if (! axl_init ())
return -1;
/* parse xml document with namespace declarations */
doc = axl_doc_parse_from_file ("test_28.xml", &error);
if (doc == NULL) {
printf ("Unable to read document: %s\n", axl_error_get (error));
axl_error_free (error);
return -1;
} /* end if */
/* call to validate namespace */
if (! axl_ns_doc_validate (doc, &error)) {
printf ("Namespace validation error: %s\n", axl_error_get (error));
axl_error_free (error);
return -1;
} /* end if */
/* get root document */
node = axl_doc_get_root (doc);
/* check default namespace */
if (! axl_ns_node_cmp (node, HTML_NS, "table")) {
printf ("expected to find a valid ns-node-cmp, but it wasn't found");
return -1;
}
/* free document */
axl_doc_free (doc);
/* terminate axl execution */
axl_end ();
return 0;
}

As a gold rule, your code must not use prefixed names (full qualified names) to check xml node names (tags), because they will make your code fragile to changes introduced in xml documents read by your application.

Instead, you must provide your namespace where the validation will take place and the local name of the node being checked (knowing that the prefix and the local name for <shaper:xml-rpc-invoke> is shaper and xml-rpc-invoke respectively).

Let's see an an example to clarify this. Assuming the following xml document:

<?xml version='1.0' ?>
<document xmlns:foo="http://www.aspl.es/schemas/shaper"
xmlns:shaper="http://another/shaper">
<!-- invoke to get customer associated data -->
<shaper:xml-rpc-invoke service="af_gestor_mecaes::customer::reference (customer_id)" register="cliente" />
<shaper:cached use="cliente.name" as="nombre"/>
<!-- get the surname 1 -->
<shaper:cached use="cliente.surname1" as="apellido1"/>
<!-- get the surname 2 -->
<shaper:cached use="cliente.surname2" as="apellido2"/>
<!-- get the hole name -->
<shaper:cached use="cliente" as="cliente"/>
<!-- get the invoice data associated -->
<shaper:xml-rpc-invoke service="af_gestor_mecaes::customer::list (0, 0)" register="customer-list" />
<!-- do a foreach iteration -->
<shaper:foreach use="customer-list" register="customer" as="_plain">
<!-- use the hole array information -->
<customer>
<shaper:cached use="customer.id" as="id" />
<shaper:cached use="customer.name" as="name" />
</customer>
<!-- terminate foreach instruction -->
</shaper:foreach>
</document>

Previous examples shows a simple shaper description, which is using shaper as prefix for its nodes. Under this situation you must not use the following to check for an xml node name:

1 if (NODE_CMP_NAME (node, "shaper:xml-rpc-invoke")) {
2  // found shaper:xml-rpc-invoke tag
3 }

This is because, as we have said, you are placing direct references to the namespace prefix declared at the document, but this is wrong. You can't ensure the user won't change the namespace binding that links your namespace with the prefix shaper.

The proper way to check xml node names (tags) in a namespace aware manner is:

1 // supposing SHAPER_NS defines the namespace string
2 if (axl_ns_node_cmp (node, SHAPER_NS, "xml-rpc-invoke")) {
3  // found xml-rpc-invoke tag
4 }

Now, the user will be able to change the binding between your namespace and the prefix used. This will enable him to use the prefix shaper for its products, without breaking your software.

NOTE: providing a document without content (at least one root node configured), will cause the function to return axl_true.

Parameters
docThe document that is being required to be checked against the XML Namespaces 1.0 rules.
errorAn optional variable where errors will be reported. If the function returns axl_false, you can call to axl_error_get to get a textual diagnostic.
Returns
axl_true if the document is namespace-valid, otherwise, axl_false is returned.

References axl_doc_get_root(), axl_error_new(), axl_false, and axl_true.