解决!谢谢你们!
你的建议让我得到答案。所以你们都应该感谢你的建议。
放置int变量的解决方案如下:
//Put my xpath into a string variable where it can evaluate my integer "counter"
String myString = "/*[local-name()='root' and namespace-uri()='DK']/*[local-name()='book' and namespace-uri()='DK']" + counter + "]/*[local-name()='item1' and namespace-uri()='DK']/*[local-name()='item2' and namespace-uri()='DK']/*[local-name()='date' and namespace-uri()='DK'][" + counter + "]"
//Then simply put that string variable into the xpath expression.
System.out.print(myString);
以下原始问题:
首先,我感谢任何帮助。提前感谢您的帮助。
我有一个需要解析的XML文件。
让我们举例说......
<root xmlns="DK">
<book>
<item1>
<item2>
<date>xxx
</date>
<date>x1x1x1
</date>
</item2>
</item1>
</book>
<book>
<item1>
<item2>
<date>yyy
</date>
<date>y1y1y1
</date>
</item2>
</item1>
</book>
</root>
所以基本上,我正在寻找节点&lt;日期和GT;用xxx然后移动到同一节点&lt;日期和GT;在下一本包含yyy的书中。
输入的xml文件将包含未知数量的重复书籍,每本书都有不同的信息。
我选择尝试这样的事情。
// I've imported from dom4j SAXreader. I probably could use something different.
import org.dom4j.io.SAXReader;
// Variables
Document document = null;
// Take input from file
SAXReader reader = new SAXReader();
document = reader.read("E:/templates/test.xml");
int counter = 0;
int numofbooks = 0;
Element root = document.getRootElement();
for ( Iterator i = root.elementIterator("book"); i.hasNext();) {
Element element = (Element) i.next();
counter = counter + 1;
numofbooks = counter;
}
System.out.println("There are " + numofbooks + " books required for processing");
while(counter != numofbooks); {
counter = counter + 1;
System.out.print("The values are: ");
// ----- This here is my problem code ----- //
System.out.print(/*[local-name()='root' and namespace-uri()='DK']/*[local-name()='book' and namespace-uri()='DK'][counter]/*[local-name()='item1' and namespace-uri()='DK']/*[local-name()='item2' and namespace-uri()='DK']/*[local-name()='date' and namespace-uri()='DK'][counter]).getStringValue());
System.out.print(" respectively");
}
我的问题在于此。因为有一些具有完全相同名称的重复节点是嵌套的,所以我使用整数计数器变量按数字抓取它们。
我的XPath表达式不明白我正在放入一个整数变量“counter”。
我可以使用任何语法来完成这项工作吗? 或者这是不可能的?
提前致谢。
DK
答案 0 :(得分:1)
我没有在您的代码中看到对XPath API的任何调用,只是注释中的一个非常令人困惑的XPath表达式。
以下代码会在 NodeList
中为您提供第一个 <date>
的{{1}}:
<item2>
鉴于您的问题中的XML代码段,上面的代码将输出:
XPath xpath = XPathFactory.newInstance().newXPath();
NodeList dates = (NodeList) xpath.evaluate("/DK:root/DK:book/DK:item1/DK:item2/DK:date[1]", document, XPathConstants.NODESET);
for (int i = 0; i < dates.getLength(); i++) {
Node item = dates.item(i);
String content = item.getTextContent().trim();
System.err.println(content);
}
请注意,XPath从1开始计数,因此xxx
yyy
是第一个元素,而不是Java中的第二个元素。
如果您不需要名称空间感知,则可以只使用date[1]
(可能会删除对"/root/book/item1/item2/date[1]"
或同等名称的调用)
如果DocumentBuilderFactory.setNamespaceAware(true);
在整个文档中是唯一的,您甚至可以将XPath表达式减少到item2
“(对于NS感知,如上所述,使用"//item2/date[1]
为两个路径段添加前缀)。< / p>
答案 1 :(得分:1)
您可以在XPath表达式中引用变量$counter
,并且可以通过定义XPathVariableResolver并将其与XPathFactory相关联来设置Java API中变量的值。
答案 2 :(得分:0)
即使存在事先未知的嵌套,也可以使用XPath表达式,如:
(//*[local-name()='root' and namespace-uri()='DK'])[$k]
其中$k
可以用正整数代替。
请注意:
上述表达式中的括号是必要的。
XPath中的索引是基于1的,而不是基于C#或C ++的0。