xmlns声明破坏了我的xPath过滤器

时间:2011-10-14 15:09:49

标签: 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 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>
返回

和文本(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>

给了我错误,matlab报告:

  

???尝试引用非结构数组的字段。

     

==&gt;中的错误测试12 phoneNumber = phoneNumberNode.getTextContent

为什么呢?我该如何避免这个错误?

2 个答案:

答案 0 :(得分:6)

如果您无法使用关联的前缀注册默认命名空间,请使用:

*[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文档

<?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>

答案 1 :(得分:0)

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执行此操作的文档:

http://www.ibm.com/developerworks/library/x-javaxpathapi/index.html#N1022D

但是,我不确定这是如何转换为Matlab的。