필터 지우기
필터 지우기

XPath query with default namespace in XML file

조회 수: 25 (최근 30일)
chris
chris 2022년 11월 25일
편집: chris 2022년 12월 2일
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일
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개)

카테고리

Help CenterFile Exchange에서 Structured Data and XML Documents에 대해 자세히 알아보기

제품


릴리스

R2021b

Community Treasure Hunt

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

Start Hunting!

Translated by