Project

Profile

Help

Understanding XML parsing with Saxonica .Net libraries

Added by Jon Koeter over 6 years ago

My question is very simple. I’m trying to read the value of an attribute of a XdmNode:

<meta xmlns="urn:dnb:stat:trafo:meta"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="urn:dnb:stat:trafo:meta meta.xsd">
         <sectionHeader fileName="result.csv"/>
         <sectionTemplate>
                   ~

I want to get “result.csv”. I have tried using enumerators, selectors etc etc. How can this be so incredibly complicated? I’ve been working with XML via .Net for years, but cannot extract a simple attribute with Saxon Xdm-things?

Right now, what comes closest to what I would think is a solution is this:

public XdmValue GetValueFromExpression(XdmNode node, string expression)
        {
            //set the processor to use licensed edition
            var processorMeta = new Processor(true);

            //combine the path to the license file
            var filePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, SaxonLicenseFileName);

            //Convert to URI (compatible with Java libraries)
            var fileUrl = new Uri(filePath).AbsoluteUri;

            //Set the URI
            processorMeta.SetProperty("http://saxon.sf.net/feature/licenseFileLocation", fileUrl);

            //Get the XPathCompiler
            var executable = processorMeta.NewXPathCompiler().Compile(expression);

            //Load selector
            var selector = executable.Load();

            //Set the contextitem to the node-parameter
            selector.ContextItem = node;

            //return the XdmValue
            return selector.Evaluate();
        }

The parameters passed are the xml shown above as XdmNode and the expression "//meta/sectionHeader[@fileName]".

This gives me an error though: 'Supplied node must be built using the same or a compatible Configuration'. And even after intensive googling I have no idea what to make of it, since I’m creating a new processor, compiler and selector.

For comparison: normally something like this would suffice: xml.SelectNode(“/Meta/SectionHeader”).Attributes[“fileName”];

Do the saxon DLL’s support a syntax like that?


Replies (2)

RE: Understanding XML parsing with Saxonica .Net libraries - Added by Michael Kay over 6 years ago

The XdmNode has very little intrinsic support for navigation within the tree: the Java version has a little more, and will get much better in the next Saxon version, but until now, you can only get the basic properties of a node, and use it as the basis for XPath expressions.

An XdmNode "belongs" to a Processor (more strictly, to its underlying Configuration) and can only be used with that Processor, so you need to use the original Processor rather than creating a new one. (The reason for this is primarily the NamePool, which is an internal mapping of node names to small integers, used to enable fast searching).

Ideally, reuse the XPathCompiler so you don't need to supply a new set of namespace bindings every time.

I would suggest keeping a handle on the XPathCompiler, having done:

compiler.DeclareNamespace("", "urn:dnb:stat:trafo:meta");

and then doing

String attval = compiler.EvaluateSingle("string(/meta/sectionHeader/@filename)", node).GetStringValue();

to get the value of the required attribute

RE: Understanding XML parsing with Saxonica .Net libraries - Added by Jon Koeter over 6 years ago

Thank you Michael. Got it to work. Had to remove "string(" and ")" from the expression (with it, it returned an empty string).

Looking forward to the newer version.

    (1-2/2)

    Please register to reply