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.
Please register to reply