xmlns声明破坏了我的xPath过滤器
我在MatLab中实现了一个非常愚蠢的xPath过滤器:xmlns声明破坏了我的xPath过滤器,xml,matlab,xpath,Xml,Matlab,Xpath,我在MatLab中实现了一个非常愚蠢的xPath过滤器: % Construct the DOM. docNode = xmlread('C:\Users\MATLAB\test.gpx'); % get the xpath mechanism into the workspace import javax.xml.xpath.* factory = XPathFactory.newInstance; xpath = factory.newXPath; % compile and evalu
% Construct the DOM.
docNode = xmlread('C:\Users\MATLAB\test.gpx');
% get the xpath mechanism into the workspace
import javax.xml.xpath.*
factory = XPathFactory.newInstance;
xpath = factory.newXPath;
% compile and evaluate the XPath Expression
expression = xpath.compile('gpx/AddressBook/Entry/PhoneNumber');
phoneNumberNode = expression.evaluate(docNode, XPathConstants.NODE);
phoneNumber = phoneNumberNode.getTextContent
使用此XML(特别是.gpx文件),它可以:
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?>
<gpx version='1.1' creator='TTTracklog V.1.13'>
<AddressBook>
<Entry>
<Name>Friendly J. Mathworker</Name>
<PhoneNumber>(508) 647-7000</PhoneNumber>
<Address hasZip="no" type="work">3 Apple Hill Dr, Natick MA</Address>
</Entry>
</AddressBook>
</gpx>
友好的J.Mathworker
(508) 647-7000
3苹果山博士,马萨诸塞州纳蒂克
返回文本(508)647-7000。
只需通过以下方式将xmlns属性添加到gpx节点:
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?>
<gpx version='1.1' creator='TTTracklog V.1.13' xmlns='http://www.topografix.com/GPX/1/1'>
<AddressBook>
<Entry>
<Name>Friendly J. Mathworker</Name>
<PhoneNumber>(508) 647-7000</PhoneNumber>
<Address hasZip="no" type="work">3 Apple Hill Dr, Natick MA</Address>
</Entry>
</AddressBook>
</gpx>
友好的J.Mathworker
(508) 647-7000
3苹果山博士,马萨诸塞州纳蒂克
给了我错误和matlab报告:
???尝试引用非结构数组的字段
在12 phoneNumber=phoneNumberNode.getTextContent测试时出错==>
为什么??我怎样才能避免这个错误呢 上面Dabbler的评论是正确的。由于已将默认名称空间添加到XML文档中,因此还必须修改XPath表达式以在新的默认名称空间中搜索节点 XPath表达式中的非限定名称(如
AddressBook
)位于null
XML命名空间中,而不是文档的默认XML命名空间中
因此,您希望以某种方式将新名称空间注册到xpath
对象中。比如:
{"foo": "http://www.topografix.com/GPX/1/1"}
然后将XPath表达式更改为:
foo:gpx/foo:AddressBook/foo:Entry/foo:PhoneNumber
这里有一些关于如何使用javax.xml.xpath
API执行此操作的文档:
但是,我不确定这到底是如何翻译成Matlab的。如果无法使用相关前缀注册默认名称空间,请使用:
*[name()= 'gpx']
/*[name()='AddressBook']
/*[name()='Entry']
/*[name() = 'PhoneNumber']
gpx/AddressBook/Entry/PhoneNumber
而不是:
*[name()= 'gpx']
/*[name()='AddressBook']
/*[name()='Entry']
/*[name() = 'PhoneNumber']
gpx/AddressBook/Entry/PhoneNumber
这里是一个完整的、基于XSLT的验证:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"*[name()= 'gpx']
/*[name()='AddressBook']
/*[name()='Entry']
/*[name() = 'PhoneNumber']
"/>
</xsl:template>
</xsl:stylesheet>
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?>
<gpx version='1.1' creator='TTTracklog V.1.13' xmlns='http://www.topografix.com/GPX/1/1'>
<AddressBook>
<Entry>
<Name>Friendly J. Mathworker</Name>
<PhoneNumber>(508) 647-7000</PhoneNumber>
<Address hasZip="no" type="work">3 Apple Hill Dr, Natick MA</Address>
</Entry>
</AddressBook>
</gpx>
<PhoneNumber xmlns="http://www.topografix.com/GPX/1/1">(508) 647-7000</PhoneNumber>
当此转换应用于提供的XML文档时:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"*[name()= 'gpx']
/*[name()='AddressBook']
/*[name()='Entry']
/*[name() = 'PhoneNumber']
"/>
</xsl:template>
</xsl:stylesheet>
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?>
<gpx version='1.1' creator='TTTracklog V.1.13' xmlns='http://www.topografix.com/GPX/1/1'>
<AddressBook>
<Entry>
<Name>Friendly J. Mathworker</Name>
<PhoneNumber>(508) 647-7000</PhoneNumber>
<Address hasZip="no" type="work">3 Apple Hill Dr, Natick MA</Address>
</Entry>
</AddressBook>
</gpx>
<PhoneNumber xmlns="http://www.topografix.com/GPX/1/1">(508) 647-7000</PhoneNumber>
友好的J.Mathworker
(508) 647-7000
3苹果山博士,马萨诸塞州纳蒂克
选中所需元素并将其复制到输出中:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"*[name()= 'gpx']
/*[name()='AddressBook']
/*[name()='Entry']
/*[name() = 'PhoneNumber']
"/>
</xsl:template>
</xsl:stylesheet>
<?xml version='1.0' encoding='ISO-8859-1' standalone='yes' ?>
<gpx version='1.1' creator='TTTracklog V.1.13' xmlns='http://www.topografix.com/GPX/1/1'>
<AddressBook>
<Entry>
<Name>Friendly J. Mathworker</Name>
<PhoneNumber>(508) 647-7000</PhoneNumber>
<Address hasZip="no" type="work">3 Apple Hill Dr, Natick MA</Address>
</Entry>
</AddressBook>
</gpx>
<PhoneNumber xmlns="http://www.topografix.com/GPX/1/1">(508) 647-7000</PhoneNumber>
(508)647-7000
我不知道MatLab,但是从XML的角度来看,现在已经将gpx(等)元素放在了名称空间中,XPath正在全局名称空间中查找它。您需要以某种方式让MatLab知道名称空间,然后在XPath表达式中限定gpx元素。如果Matlab中没有注册名称空间的机制,您可以使用这样的表达式:*[name()='gpx']/*[name()='AddressBook']/*[name()='Entry']/*[name()='PhoneNumber']
.\u Mariano:我的答案有用吗?你说得对!我应该声明一个路径名。我已经在matlab论坛上发布了这个问题。我会在他们回答我后立即报告。应该准确翻译,因为它使用Java类。对于特定于MATLAB的实现,我在这个博客评论中发布了一个示例:您仍然需要为NamespaceContext使用Java类代码:e1=xPath.compile('*[name()=“gpx”]/*[name()=“trk”]);s=e1.evaluate(gpx,XPathConstants.NODESET);sNumber=s.getLength代码>编译并返回精确值。而e2=xPath.compile('*[name()=“gpx”]/*[name()=“trk[1]”]/*[name()=“trkseg”]”);s=e2.evaluate(gpx,XPathConstants.NODESET);sNumber=s.getLength代码>始终返回0值。为什么?这是第二个表达式的“[1]”吗?@Mariano:当然。名称只能包含字母数字字符(以字母开头)--而不能包含[]
。你真的想要:*[name()='trk'][1]
你就是男人!最后一件事:属性呢?例如:如何使用这种符号获得纬度和经度?我需要使用name()重写类似于gpx/trk[1]/trkseg[1]/trkpt[2]/@lat
的内容。@Mariano:在您提供的XML文档中,没有lat
属性(也没有名称可能代表经度的属性)。因此,我想我还没有看到用于--use:*[name()的XML文档='gpx']/*[name()='trk'][1]/*[name()='trkseg'][1]/*[name()='trkpt'][2]/@lat
看这个:属性“lat”和“lon”写在trkpt
标记中。无论如何,你是对的!;)