【发布时间】:2018-01-12 15:07:07
【问题描述】:
我有以下程序:
package xpath;
import java.io.StringReader;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Node;
import org.dom4j.io.SAXReader;
public class TryXPath
{
public static void say(String message) { System.out.println(message); }
public static String mainDocumentXML
= "<GetAvailableProductsResponse xmlns=\"http://api.onecommunications.com/pricing_availability/\">" +
" <GetAvailableProductsResult>" +
" <Products>" +
" <Product>" +
" <ProductID>101236004</ProductID>" +
" <BaseProductName>Widget1</BaseProductName>" +
" </Product>" +
" <Product>" +
" <ProductID>101236005</ProductID>" +
" <BaseProductName>Widget2</BaseProductName>" +
" </Product>" +
" <Product>" +
" <ProductID>101236006</ProductID>" +
" <BaseProductName>Widget3</BaseProductName>" +
" </Product>" +
" </Products>" +
" </GetAvailableProductsResult>" +
"</GetAvailableProductsResponse>";
public static void main(String[] args)
{
String PRODUCTS_NODE_PATH = "/*[name()='GetAvailableProductsResponse']/*[name()='GetAvailableProductsResult']/*[name()='Products']";
String PRODUCTS_PATH = "/*[name()='Product']";
try
{
org.dom4j.io.SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(mainDocumentXML));
Node root = document.selectSingleNode(PRODUCTS_NODE_PATH);
if (root == null)
{
say("No root");
}
else
{
List<Node> productsNodeList = root.selectNodes(PRODUCTS_NODE_PATH + PRODUCTS_PATH);
say("products node list size=" + productsNodeList.size());
for (Node node : productsNodeList)
{
say("node: " + node.asXML());
say("name: " + node.getName());
say("id: " + node.selectSingleNode("//*[local-name()='ProductID']").getText());
}
}
}
catch (Exception e) { e.printStackTrace(); }
}
}
它解析给定的 XML;一部分会生成一个包含 3 个产品节点的列表,然后我要做的是访问每个节点中的项目。但是,我使用的 ProductID 的 XPath 表达式不正确 ("//*[local-name()='ProductID']");它显然搜索主文档,而不是调用 selectSingleNode() 方法的节点。
程序的输出:
products node list size=3
node: <Product xmlns="http://api.onecommunications.com/pricing_availability/"> <ProductID>101236004</ProductID> <BaseProductName>Widget1</BaseProductName> </Product>
name: Product
id: 101236004
node: <Product xmlns="http://api.onecommunications.com/pricing_availability/"> <ProductID>101236005</ProductID> <BaseProductName>Widget2</BaseProductName> </Product>
name: Product
id: 101236004
node: <Product xmlns="http://api.onecommunications.com/pricing_availability/"> <ProductID>101236006</ProductID> <BaseProductName>Widget3</BaseProductName> </Product>
name: Product
id: 101236004
请注意,“id”的所有值都来自第一个节点,而不是调用 selectSingleNode() 的节点的 ProductID 值。
我尝试了各种“.”、“/”、没有“/”、“::”等的组合,但我似乎找不到将返回 ProductID 节点的 XPath 表达式列表中的单个产品节点。我该怎么做?
【问题讨论】:
-
也有可能是程序无权访问命名空间,所以我也一直在玩local-name。