我们来看一个简单的XML文档:
<x>
<e>
<e>
<e>Whatever 1</e>
</e>
</e>
<e>
<e>
<e>Whatever 2</e>
</e>
</e>
<e>
<e>
<e>Whatever 3</e>
</e>
</e>
</x>
使用标准的org.w3c.dom,我可以通过执行..来获取X中的节点。
NodeList fullnodelist = doc.getElementsByTagName("x");
但如果我想返回下一组“e”,我会尝试使用类似的东西。
Element element = (Element) fullnodelist.item(0);
NodeList nodes = pelement.getElementsByTagName("e");
期望它返回“3”节点(因为有3组“e”),但相反,它返回“9” - 因为它会以“e”显示所有条目。
在上述情况下这很好,因为我可能会迭代并找到我正在寻找的东西。我遇到的问题是,当XML文件如下所示:
<x>
<e>
<pattern>whatever</pattern>
<blanks>
<e>Something Else</e>
</blanks>
</e>
<e>
<pattern>whatever</pattern>
<blanks>
<e>Something Else</e>
</blanks>
</e>
</x>
当我请求“e”值时,它返回4,而不是(我期望的)2。
我只是不了解DOM解析的工作原理?通常在过去我使用自己的XML文档,所以我永远不会命名这样的项目,但不幸的是,这不是我的XML文件,我没有选择像这样工作。
我认为我会做的是编写一个“向下钻取”节点的循环,以便我可以将每个节点组合在一起......
public static NodeList getNodeList(Element pelement, String find)
{
String[] nodesfind = Utilities.Split(find, "/");
NodeList nodeList = null;
for (int i = 0 ; i <= nodesfind.length - 1; i++ )
{
nodeList = pelement.getElementsByTagName( nodesfind[i] );
pelement = (Element)nodeList.item(i);
}
// value of the nod we are looking for
return nodeList;
}
..所以如果你把“s / e”传递给函数,它会返回我正在寻找的2个节点(或元素,也许我使用的术语不正确?)。相反,它返回该节点内的所有“e”节点。
我正在使用J2SE,所以选项相当有限。我不能使用任何第三方XML Parsers。
无论如何,如果有人还在我身边并有建议,我们将不胜感激。
答案 0 :(得分:3)
如果您是手动遍历Xml,请尝试使用一个变量,当您遇到每个“e”标记时,该变量会递增,然后在您离开时递减。
如果源代码遵循您给出的上述示例,则可以使用简单的if语句在执行操作之前确保计数器等于2(假设它从0开始)
我可能会稍微误解你的确切问题,但我希望这会有所帮助。
答案 1 :(得分:2)
比计数器更好的解决方案是检查每个返回的节点,看看它们是否具有正确的父节点。
getChildNodes()
不仅返回所有子项,还返回所有后代(即完整子树)。
Element element = doc.getDocumentElement();
NodeList nodeList = element.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++ ) {
if (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE && nodeList.item(i).getParentNode().isSameNode(element)) {
Element childElement = (Element) nodeList.item(i);
if (childElement.getTagName().equals("someTagName")) {
handleSomeTag(childElement);
} else if (childElement.getTagName().equals("someOtherTagName")) {
handleSomeOtherTag(childElement);
}
}
}
getElementsByTagName()
不仅返回具有该标记名的所有子项,还返回具有该标记名的所有后代(即完整子树中具有该名称的所有标记)。
Element element = doc.getDocumentElement();
NodeList nodeList = element.getElementsByTagName("someTag");
for (int i = 0; i < nodeList.getLength(); i++ ) {
if (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE && nodeList.item(i).getParentNode().isSameNode(element)) {
Element childElement = (Element) nodeList.item(i);
handleSomeTag(childElement);
}
}
nodeList = element.getElementsByTagName("someOtherTag");
for (int i = 0; i < nodeList.getLength(); i++ ) {
if (nodeList.item(i).getNodeType() == Node.ELEMENT_NODE && nodeList.item(i).getParentNode().isSameNode(element)) {
Element childElement = (Element) nodeList.item(i);
handleSomeOtherTag(childElement);
}
}
答案 2 :(得分:1)
您需要了解XPath。 Java 1.5中有一个XPathFactory,您可以创建一个XPath来命名您想要的特定“e”。