XPath query with default namespace in XML file

Matlab introduced a MATLAB API for XML Processing (I believe in 2021a).
I am using this API with XPath expressions to extract data from XML files. However, this fails when the XML file has a default namespace registered.
For example with this XML file test.xml:
<books xmlns="http://www.contoso.com/books" xmlns:i="http://www.contoso.com/currency">
<book>
<title>Title</title>
<author>Author Name</author>
<i:price>5.50</i:price>
</book>
</books>
Using the following snippet:
import matlab.io.xml.dom.*
import matlab.io.xml.xpath.*
xmlFilePath = "path\to\test.xml";
xmlDom = parseFile(Parser, xmlFilePath);
xpathPrice = "//i:price";
xpathAuthor = "//author";
res = evaluate(Evaluator, xpathPrice, xmlDom)
works for xpathPrice but fails for xpathAuthor (in the sense that it returns an empty result instead of the author node from the example).
Browsing through the different options, I could not come up with a solution. I am working on Matlab 2021b.
I know that I could use getElementsByTagName but I do require the functionality provided by XPath to identify nodes.
Are there any hints on how I could get that working?
Thanks!

 採用された回答

Sakshay
Sakshay 2022 年 11 月 29 日

0 投票

Hello Chris,
As per my understanding, you are trying to access elements of an XML file, using XPath. But it seems that the elements with a default namespace having no prefix are not being captured.
This problem here seems to be with how XPath works, rather than in the MATLAB API.
Elements without a prefix, can be accessed using the "local-name()" attribute. As an example, for your case, the query would look like:
xPathAuthor = '//*[local-name()="book"]';
res = evaluate(Evaluator, xPathAuthor, xmlDom);
For information, on the XPath Evaluator Package, you can refer to the following documentation:

1 件のコメント

chris
chris 2022 年 12 月 2 日
Hi,
thanks for your reply. After some more research, it looks like you are right and this is some weird behavior of XPath. Personally, I find the solution not very satisfying but that's how it is.
For interested people, another workaround would be to use a default prefix (as described here: Abstract base class for namespace prefix resolvers). Something along these lines
import matlab.io.xml.xpath.*
evalObj = Evaluator();
evalObj.PrefixResolver = myPrefixResolver;
xpathAuthor = "//def:author";
res = evaluate(evalObj, xpathAuthor, xmlDom);
with the custom prefix resolver:
classdef myPrefixResolver < matlab.io.xml.xpath.PrefixResolver
methods
function url = getNamespaceForPrefix(resolver,prefix)
if prefix == "i"
url = "http://www.contoso.com/currency";
else
url = "http://www.contoso.com/books";
end
end
end
end
The disadvantage is, that one has to know the namespace URLs beforehand.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

製品

リリース

R2021b

質問済み:

2022 年 11 月 25 日

編集済み:

2022 年 12 月 2 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by