2015-09-26 46 views
2

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

下面是我写的代码和示例XML文件。 例如的NM109_BillingProviderIdentifierTS837_2000A_Loop元件的深度为4。

父节点是:TS837_2000A_Loop < NM1_SubLoop_2 < TS837_2010AA_Loop < NM1_BillingProviderName 作为NM109_BillingProviderIdentifierNM1_BillingProviderName子并且因此NM1_BillingProviderNameTS837_2000A_Loop相对深度为4(包括TS837_2000A_Loop)。

package com.xmlexamples; 
import java.io.File; 
import java.io.FileInputStream; 

import javax.xml.parsers.DocumentBuilder; 
import javax.xml.parsers.DocumentBuilderFactory; 
import javax.xml.xpath.XPath; 
import javax.xml.xpath.XPathConstants; 
import javax.xml.xpath.XPathFactory; 

import org.w3c.dom.Document; 


public class XmlParser { 

public static void main(String[] args) throws Exception { 
     DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); 
     dbf.setValidating(false); 
     DocumentBuilder db = dbf.newDocumentBuilder(); 
     Document doc = db.parse(new FileInputStream(new File("D://sample.xml"))); 

     XPathFactory factory = XPathFactory.newInstance(); 
     XPath xpath = factory.newXPath(); 
     String expression;  
     expression = "count(NM109_BillingProviderIdentifier/preceding-sibling::TS837_2000A_Loop)+1";     
     Double d = (Double) xpath.compile(expression).evaluate(doc, XPathConstants.NUMBER);  
     System.out.println("position from TS837_2000A_Loop " + d); 

    } 
} 

<?xml version='1.0' encoding='UTF-8'?> 
 
<X12_00501_837_P xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
 
    <TS837_2000A_Loop> 
 
     <NM1_SubLoop_2> 
 
      <TS837_2010AA_Loop> 
 
       <NM1_BillingProviderName> 
 
        <NM103_BillingProviderLastorOrganizationalName>VNA of Cape Cod</NM103_BillingProviderLastorOrganizationalName> 
 
        <NM109_BillingProviderIdentifier>1487651915</NM109_BillingProviderIdentifier> 
 
       </NM1_BillingProviderName> 
 
       <N3_BillingProviderAddress> 
 
        <N301_BillingProviderAddressLine>8669 NORTHWEST 36TH ST </N301_BillingProviderAddressLine> 
 
       </N3_BillingProviderAddress> 
 
      </TS837_2010AA_Loop> 
 
     </NM1_SubLoop_2> 
 
    </TS837_2000A_Loop> 
 
</X12_00501_837_P> 

+2

一行4412个字符的单行XML?超过4kB?请花一点时间(1)将您的示例XML最小化为理解您的问题所需的内容,以及(2)布局示例以使其可读。请花一分钟阅读[mcve]。另外,请说明“相对位置”。角色位置?节点位置?深度? – Abel

回答

1

求任意节点的深度枢转方法是通过计数其祖先(包括父,母等的亲本):

count(NM109_BillingProviderIdentifier/ancestor-or-self::*) 

这会给你数到根。要获得相对计数,即从根以外任何东西,假设名称不重叠,你可以这样做:

count(NM109_BillingProviderIdentifier/ancestor-or-self::*) 
- count(NM109_BillingProviderIdentifier/ancestor::TS837_2000A_Loop/ancestor::*) 

根据是否当前,或基本元素应该被列入计数,请使用ancestor-or-selfancestor轴。


PS:你应该感谢Pietro Saccardi这么好心让您的文章和你的大(在一行中的4kB ..)样本XML具有可读性。

+0

@Pietro Saccardi:非常感谢您让我的文章可读。在撰写我未来的帖子时,我会牢记这一点。 – DaisyD

+0

我试过了你建议的表达式,但我总是得到0。在我的代码中有什么问题吗? – DaisyD

+0

我错过了//在NM109_BillingProviderIdentifier前面,它现在给我算了。让我测试我正在开发的功能。谢谢。 – DaisyD