2015-09-26 96 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