объявление xmlns сломало мой фильтр xPath
я понял действительно глупый фильтр xPath в MatLab:
% Construct the DOM.
docNode = xmlread('C:UsersMATLABtest.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 (в частности, a .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 ответов
комментарий дилетанта выше верен. Поскольку в XML-документ добавлено пространство имен по умолчанию, необходимо также изменить выражение XPath для поиска узлов в новом пространстве имен по умолчанию.
неквалифицированные имена в выражениях XPath (например,AddressBook
) в null
пространство имен XML, а не пространство имен XML по умолчанию документа.
таким образом, вы хотите каким-то образом зарегистрировать свое новое пространство имен с помощью
если вы не можете зарегистрировать пространство имен по умолчанию со связанным префиксом, используйте:
*[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>