我试图根据给定的xpath提取内容。当它只是我想要提取的一个元素时,没有问题。当我有一个匹配该xpath的项目列表时,我得到节点列表,我可以提取值。
但是,有几个项目相互关联形成一个组,并且该组重复自己。
我能做的一种方法是获取所有这些组的父节点的节点列表,然后应用基于SAX的解析技术来提取信息。但这将引入特定于模式的编码。我想让它变得通用。 离。
<html><body>
<!--... a lot divs and other tags ... -->
<div class="divclass">
<item>
<item_name>blah1</item_name>
<item_qty>1</item_qty>
<item_price>100</item_price>
</item>
</div>
<div class="divclass">
<item>
<item_name>blah2</item_name>
<item_qty>2</item_qty>
<item_price>200</item_price>
</item>
</div>
<div class="divclass">
<item>
<item_name>blah3</item_name>
<item_qty>3</item_qty>
<item_price>300</item_price>
</item>
</div>
</body></html>
我可以轻松编写 this xml的代码,但不能编写可以解析任何给定规范的通用代码。
我应该能够从上方创建list
map
attribute-value
。
有没有人试过这个?
修改 输入xpath列表:
1. "html:div[@class='divclass']/item/item_name"
2. "html:div[@class='divclass']/item/item_qty"
3. "html:div[@class='divclass']/item/item_price"
简单文本中的预期输出:
item_name:blah1;item_qty:1;item_price:100
item_name:blah2;item_qty:2;item_price:200
item_name:blah3;item_qty:3;item_price:300
这里的关键点是,如果我单独应用每个xpath,它将垂直取出结果,即第一个将获取所有item_names,第二个将获取所有qtys。所以我将放松这些内容中的相互关系。
希望这能清除我的要求。
由于 Nayn
答案 0 :(得分:3)
我不确定我是否提出了您的问题,但听起来您想在HTML文档上使用XPath。
要使用XPath,需要精心构建的HTML文档。 Java有几种HTML解析器; this article比较其中4个。
HtmlCleaner似乎提供了你想要的东西。它允许在“清理的”HTML文档上执行XPath的子集。显然它不支持完整的XPath表达式,请参阅the documentation。
如果您需要比HtmlCleaner支持的更复杂的XPath表达式,则可能需要将javax.xml.xpath包与格式良好的XHTML文档一起使用。 JTidy可以将HTML文档转换为XHTML文档。
我希望这能回答你的问题。
答案 1 :(得分:2)
我认为XQuery是屏幕抓取的绝佳解决方案。您可以使用Saxon处理器来执行xqueries。此外,您可以使用Piggy Bank Firefox扩展来轻松找到关于要从网页中提取的内容的XPath表达式,您可以在xqueries中使用它。
答案 2 :(得分:1)
为什么不分两步应用XPath。
首先获取记录的XPath(输出中的行):
//div[@class='divclass']/item
然后XPath(s)获取相对于每条记录的字段(列):
item_name
item_qty
item_price
这是工作代码(在Javascript,Windows脚本中),为您提供所需的输出:
var doc = new ActiveXObject("MSXML.DOMDocument");
doc.load("test.xml");
// XPATH #1
var recordXPath = "//div[@class='divclass']/item";
// XPATHS #2, in a dictionary ("field name":"XPath")
var fieldXPaths = { item_name : "item_name",
item_qty : "item_name",
item_price : "item_price" };
var items = doc.selectNodes(recordXPath);
for (var itemCtr = 0; itemCtr < items.length; itemCtr++) {
var item = items[itemCtr];
var fieldEntries = [];
for (var fieldName in fieldXPaths) {
var fieldXPath = fieldXPaths[fieldName];
var fieldNode = item.selectSingleNode(fieldXPath);
fieldEntries.push(fieldNode.tagName + ":" + fieldNode.text);
}
WScript.Echo(fieldEntries.join(";"));
}
答案 3 :(得分:0)
我不明白你想要实现什么以及它与XPath的关系。如果要将XML映射到Java对象,那么JAXB可能有所帮助,但它基于XML模式,而不是基于XPath。
答案 4 :(得分:0)
我不知道这是否有帮助,但我使用XSLT从数据转向HTML。在我看来,你只需要稍微构建一下XPATH执行,而XSLT对此有好处。