Java 如何使用XPATH获取XML元素的相对深度

Java 如何使用XPATH获取XML元素的相对深度,java,xml,xpath,Java,Xml,Xpath,我试图从给定XML文件中的特定元素中找到给定XML元素的相对深度,我尝试使用XPATH,但我不太熟悉XML解析,也没有得到期望的结果。我还需要在计数时忽略数据元素 下面是我编写的代码和示例XML文件。 例如,来自TS837\U 2000A\u Loop元素的NM109\u BillingProviderIdentifier的深度为4 父节点是:TS837_2000A_Loop

我试图从给定XML文件中的特定元素中找到给定XML元素的相对深度,我尝试使用XPATH,但我不太熟悉XML解析,也没有得到期望的结果。我还需要在计数时忽略数据元素

下面是我编写的代码和示例XML文件。 例如,来自
TS837\U 2000A\u Loop
元素的
NM109\u BillingProviderIdentifier
的深度为4

父节点是:
TS837_2000A_Loop
由于
NM109\u BillingProviderIdentifier
NM1\u BillingProviderName
的子项,因此
NM1\u BillingProviderName
TS837\u 2000A\u循环的相对深度为4(包括
TS837\u 2000A\u循环

package com.xml示例;
导入java.io.File;
导入java.io.FileInputStream;
导入javax.xml.parsers.DocumentBuilder;
导入javax.xml.parsers.DocumentBuilderFactory;
导入javax.xml.xpath.xpath;
导入javax.xml.xpath.XPathConstants;
导入javax.xml.xpath.XPathFactory;
导入org.w3c.dom.Document;
公共类XmlParser{
公共静态void main(字符串[]args)引发异常{
DocumentBuilderFactory dbf=DocumentBuilderFactory.newInstance();
dbf.setValidating(false);
DocumentBuilder db=dbf.newDocumentBuilder();
Document doc=db.parse(新文件输入流(新文件(“D://sample.xml”));
XPathFactory=XPathFactory.newInstance();
XPath=factory.newXPath();
字符串表达式;
expression=“count(NM109\u BillingProviderIdentifier/previous sibling::TS837\u 2000A\u Loop)+1”;
Double d=(Double)xpath.compile(expression).evaluate(doc,XPathConstants.NUMBER);
系统输出打印LN(“从TS837_2000A_回路开始的位置”+d);
}
}

科德角VNA酒店
1487651915
西北36街8669号

获取任何节点深度的关键方法是计算其祖先(包括父节点、父节点的父节点等):

这会让你数到根。要获取相对计数,即从根以外的任何位置获取,假设名称不重叠,可以执行以下操作:

count(NM109_BillingProviderIdentifier/ancestor-or-self::*)
- count(NM109_BillingProviderIdentifier/ancestor::TS837_2000A_Loop/ancestor::*)
根据当前元素还是基本元素应包含在计数中,使用
祖先或self
祖先



PS:您可能应该感谢您如此友好地使您的文章和您庞大的(一行4kB)示例XML可读。

4412个字符的一行XML?超过4kB?请花点时间(1)将示例XML最小化到理解问题所需的程度,(2)布局示例,使其可读。请花一分钟阅读。此外,请解释“相对位置”。角色位置?节点位置?深度?@Pietro Saccardi:非常感谢你让我的文章可读性好。在写我未来的帖子时,我会记住这一点。我尝试了你建议的表达方式,但我总是得到0。我的代码有什么问题吗?我错过了//在NM109_BillingProviderIdentifier前面,它正在给我计数。让我测试一下我正在开发的功能。谢谢。@DaisyD,添加
/
意味着“在树的任何深度搜索”。我不知道您的全部需求,但是如果您有多个元素要搜索,您可能希望在每次使用XPath时放入一个循环并将焦点设置为父元素。如果是这样的话,使用XSLT可能会更好,在这样的任务中更容易(但是需要你,学习XSLT……),我还需要考虑除了叶节点之外的其他元素。对于N301BIGPROVER ADADESRSLIN,它应该考虑NM1BILIN PosivRealNoD,并且计数应该是5。
count(NM109_BillingProviderIdentifier/ancestor-or-self::*)
- count(NM109_BillingProviderIdentifier/ancestor::TS837_2000A_Loop/ancestor::*)