2014-01-14 69 views
1

我想從使用XPath的請求中提取'PartyID'。這個請求是以XML的形式。XPATH將不起作用

這裏是XML:

<?xml version="1.0" encoding="UTF-8"?> 
    <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"  xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> 
<soapenv:Body> 
<s1:invokerules xmlns:s1="http://rules.kmtool.abc.com"><s1:arg0><![CDATA[<?xml version="1.0" encoding="UTF-8"?> 
    <kbdInitiateRequest> 
    <kmTestHeader> 
     <MessageId>USER1_MSG1</MessageId> 
      <TestDate>08/07/2008 07:34:15</TestDate> 
      <TestReference> 
      <ConductorReference> 
       <InvokeIdentifier> 
        <RefNum>USER1_Ref1</RefNum> 
       </InvokeIdentifier> 
      </ConductorReference> 
     </TestReference> 
     <TestParty> 
      <ConductorParty> 
       <Party PartyID="123456789" AgencyID="DUNS"> 
        <TestContact> 
         <DetailedContact> 
               <ContactName>Michael Jackson</ContactName> 
          <Telephone>02071059053</Telephone> 
          <TelephoneExtension>4777</TelephoneExtension> 
          <Email>[email protected]</Email> 
          <Title>Mr</Title> 
          <FirstName>Michael</FirstName> 
          <Initials>MJ</Initials> 
         </DetailedContact> 
        </TestContact> 
       </Party> 
      </ConductorParty> 
      <PerformerParty> 
       <Party PartyID="987654321" AgencyID="DUNS"> 
       </Party> 
      </PerformerParty> 
     </TestParty> 
    </kmTestHeader> 
    <kmToolMessage> 
     <controlNode> 
      <userRequest>INITIATE</userRequest> 
     </controlNode> 
     <customer> 
      <circuitID>000111333777</circuitID> 
    </customer> 
</kmToolMessage> 
</kbdInitiateRequest> 

]]></s1:arg0> 
</s1:invokerules> 
</soapenv:Body> 
</soapenv:Envelope> 

我有一個方法,在我的Java代碼調用getPartyId()。該方法應該從XML中提取PartyID。但是,無論使用哪種XPath查詢,我都無法獲得此方法返回PartyID,這是我需要幫助的地方。

這裏是getPartyId方法:

private String getPartyId(String xml) throws XPathExpressionException 
    {  
     XPathFactory xPathfactory = XPathFactory.newInstance(); 
     XPath xpath = xPathfactory.newXPath();  
     xpath.setNamespaceContext(new NamespaceContext() { 
      public String getNamespaceURI(String prefix) { 
       if (prefix == null) throw new NullPointerException("Null prefix"); 
       else if ("SOAP-ENV".equals(prefix)) return "http://schemas.xmlsoap.org/soap/envelope/"; 
       else if ("xml".equals(prefix)) return XMLConstants.XML_NS_URI; 
       return XMLConstants.NULL_NS_URI; 
      } 

      public String getPrefix(String uri) { 
       throw new UnsupportedOperationException(); 
      } 

      public Iterator getPrefixes(String uri) { 
       throw new UnsupportedOperationException(); 
      } 
     }); 

     XPathExpression expr = xpath.compile("/SOAP-ENV:Envelope/SOAP-ENV:Body/*/*/*/*/*/*/*/*/*/*/*[local-name()='PartyID']/text()"); 

     InputSource source = new InputSource(new StringReader(xml)); 

     String dunsId = (String) expr.evaluate(source,XPathConstants.STRING); 

     return dunsId; 
    } 

我認爲,問題出在XPathExpression:

XPathExpression expr = xpath.compile("/SOAP-ENV:Envelope/SOAP-ENV:Body/*/*/*/*/*/*/*/*/*/*/*[local-name()='PartyID']/text()"); 

我已經嘗試了數「expr的」替代品然而,這些都沒有工作。有沒有人有任何想法?

+0

糾正我,如果我錯了,但你的'local-name()'的用法不會檢索任何東西,因爲在你的例子中沒有**節點**。如果你想提取'Party'節點的**屬性**(這是我假設你想要做的),那麼你可以使用像'// Party [@PartyID] [1]'(在你的示例將返回'123456789'),您可以更改編號'[1]'來指定要訪問哪個'Party'節點。 –

回答

1

因爲xml你需要解析是坐在一個CDATA塊內,你需要重新pa在訪問其中的數據之前,請輸入s1:arg0的值。

你需要做的這2個步驟

  • 您需要訪問arg0節點在http://rules.kmtool.abc.com命名空間。

既然你沒有此內xmlns來NamespaceContext,則可以使用:

/SOAP-ENV:Envelope/SOAP-ENV:Body/*[local-name()='invokerules'] /*[local-name()='arg0']/text()

  • 然後,您需要把這個值加載到另一個InputSource。 的PartyId屬性可以通過路徑訪問:

kbdInitiateRequest/kmTestHeader/TestParty/ConductorParty/Party/@PartyID

(無需使用local-name(),因爲沒有任何xmlnsCDATA

+0

這工作!感謝您的幫助 :) – Cormac90

0

請注意,您的內部xml位於CDATA節點內部。 所以basiclly你試圖查詢CDATA內部XML的路徑。

由於此線程狀態 Xpath to the tag inside CDATA

看來這是不可能的:(

我建議採取在CDATA裏面的代碼,並將其解析到一個新的XML文檔和查詢這一點。

謝謝, 埃米爾

+0

正確,但技術上CDATA內部的內容不是XML。如果它不在CDATA內部,它將是XML; CDATA的意思是「字符數據」,其唯一目的是說「這裏的東西看起來像XML,但不要被愚弄,它只是普通的字符。」因此,理想情況下,如果您想將其視爲XML,則不會將其放入CDATA中。 –