我有一个以下结构的XML文件:
<?xml version="1.0" encoding="utf-8"?>
<root>
<ArrayOfLocationDTO xmlns:xsi="foo1" xmlns:xsd="foo2" xmlns="foo3">
<LocationDTO ~some data~>~child nodes etc~</LocationDTO>
<LocationDTO ~some data~>~child nodes etc~</LocationDTO>
... ... ...
<LocationDTO ~some data~>~child nodes etc~</LocationDTO>
<LocationDTO ~some data~>~child nodes etc~</LocationDTO>
</ArrayOfLocationDTO>
</root>
我正试图从那里抓住所有'LocationDTO'。我的代码看起来像这样:
XPath xpath = XPathFactory.newInstance().newXPath();
DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
DocumentBuilder builder = builderFactory.newDocumentBuilder();
File XMLPath=new File(Environment.getExternalStorageDirectory(), "XMLSource.xml");
Document document = builder.parse(XMLPath);
NodeList nodes = (NodeList) xpath.evaluate("//LocationDTO", document, XPathConstants.NODESET);
int count=nodes.getLength();
我的问题是除非我从XML源手动删除'ArrayOfLocationDTO',否则代码什么也找不到。 为什么ArrayOfLocationDTO会阻止我的代码正常工作?如何在没有编程删除ArrayOfLocationDTO的情况下使其工作(我认为后者是一种“脏解决方案”)?
答案 0 :(得分:1)
ArrayOfLocationDTO具有属性xmlns =“foo3”。此属性是极少数具有特殊含义的XML属性之一:具体而言,它意味着ArrayOfLocationDTO及其中的每个标记都具有名称空间“foo3”(每个XML标记都有一个本地名称,并且 - 可选 - 一个名称空间 - 这是一个由xmlns语法之一引入的字符串)。
这意味着您的文档没有名称“LocationDTO”的标记。 “LocationDTO”只是该名称的本地部分。
您有两种选择:
使用函数local-name:// * [local-name()='LocationDTO']找到本地名称的标签;到目前为止,这是您案例中最快的解决方案(简单搜索,小文档,单个命名空间)
建立命名空间上下文(使用,如果我没记错的话,使用setNamespaceContext)将“foo3”绑定到任意前缀(例如“f”)并使用query:// f:LocationDTO