Объявление xmlns сломало мой фильтр xPath - PullRequest
7 голосов
/ 14 октября 2011

Я реализовал действительно глупый фильтр xPath в MatLab:

% 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:

??? Попытка ссылки на поле неструктурного массива.

Ошибка в ==> тесте в 12 phoneNumber = phoneNumberNode.getTextContent

Почему? Как я могу избежать этой ошибки?

Ответы [ 2 ]

6 голосов
/ 09 ноября 2011

Если вы не можете зарегистрировать пространство имен по умолчанию с соответствующим префиксом, используйте:

*[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>
0 голосов
/ 14 октября 2011

Комментарий Дабблера выше верен.Поскольку вы добавили пространство имен по умолчанию в ваш XML-документ, вы также должны изменить выражение XPath для поиска узлов в вашем новом пространстве имен по умолчанию.

Неквалифицированные имена в выражениях XPath (например, AddressBook) находятся в пространстве имен XML null, а не в пространстве имен 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, точно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...