2012-06-05 131 views
1

我很難嘗試使用Xpath解析XML內容。 Xml包含名稱空間信息。我試圖創建一個NameSpaceContextImp(在jdk中NameSpaceContext接口的apache WS commons實現)來將namaspace前綴映射到URI,但是無法成功查詢xml文檔。當我在http://chris.photobooks.com/xml/default.htm上使用在線xpath測試工具時,我使用的xpath查詢出現了我預期的節點/元素。所以我想弄清楚我做錯了什麼。我正在提供xml文檔和示例代碼片段。我會很感激任何反饋。作爲說明,我已經嘗試了使用或不使用名稱空間前綴的xpath查詢。使用jdk xpath解析xml與名稱空間問題

NamespaceContextImpl namespaceContext = new NamespaceContextImpl(); 
namespaceContext.startPrefixMapping("wsp", "http://schemas.xmlsoap.org/ws/2002/12/policy"); 
namespaceContext.startPrefixMapping("L7p", "http://www.layer7tech.com/ws/policy"); 
String policyXml = "xml content that is pasted below" 
InputSource inputSource = new InputSource(new StringReader(policyXml)); 
XPathFactory xpathFactory = XPathFactory.newInstance(); 
XPath xPath = xpathFactory.newXPath(); 
xPath.setNamespaceContext(namespaceContext); 
XPathExpression xpathExpression = xPath.compile("/wsp:Policy/wsp:All"); 
String evaluation = xpathExpression.evaluate(inputSource); 
if (evaluation.trim().length() > 0) { 
    System.out.println(evaluation); 
} 


    <?xml version="1.0" encoding="UTF-8"?> 
<wsp:Policy xmlns:L7p="http://www.layer7tech.com/ws/policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2002/12/policy"> 
    <wsp:All wsp:Usage="Required"> 
     <L7p:SetVariable> 
      <L7p:AssertionComment assertionComment="included"> 
       <L7p:Properties mapValue="included"> 
        <L7p:entry> 
         <L7p:key stringValue="RIGHT.COMMENT"/> 
         <L7p:value stringValue="Used to enable message logging, Null (allow MSGDEBUG Header to set level), 0 - default,1 - Medium,2 - Full"/> 
        </L7p:entry> 
       </L7p:Properties> 
      </L7p:AssertionComment> 
      <L7p:Base64Expression stringValue=""/> 
      <L7p:VariableToSet stringValue="LOCAL_POLICY_DEBUG_LEVEL"/> 
     </L7p:SetVariable> 
     <L7p:Include> 
      <L7p:PolicyGuid stringValue="ec1f4166-4299-4e44-bf9d-c5c2a9f0c894"/> 
     </L7p:Include> 
     <L7p:SslAssertion> 
      <L7p:Option optionValue="Optional"/> 
     </L7p:SslAssertion> 
     <wsp:OneOrMore L7p:Enabled="false" wsp:Usage="Required"> 
      <L7p:SpecificUser> 
       <L7p:Enabled booleanValue="false"/> 
       <L7p:IdentityProviderOid longValue="-2"/> 
       <L7p:UserLogin stringValue="test"/> 
       <L7p:UserName stringValue="test"/> 
       <L7p:UserUid stringValue="58916874"/> 
      </L7p:SpecificUser> 
      <L7p:SpecificUser> 
       <L7p:Enabled booleanValue="false"/> 
       <L7p:IdentityProviderOid longValue="-2"/> 
       <L7p:UserLogin stringValue="test"/> 
       <L7p:UserName stringValue="test"/> 
       <L7p:UserUid stringValue="58916873"/> 
      </L7p:SpecificUser> 
      <L7p:SpecificUser> 
       <L7p:Enabled booleanValue="false"/> 
       <L7p:IdentityProviderOid longValue="-2"/> 
       <L7p:UserLogin stringValue="test"/> 
       <L7p:UserName stringValue="test"/> 
       <L7p:UserUid stringValue="58916876"/> 
      </L7p:SpecificUser> 
      <L7p:SpecificUser> 
       <L7p:Enabled booleanValue="false"/> 
       <L7p:IdentityProviderOid longValue="-2"/> 
       <L7p:UserLogin stringValue="test"/> 
       <L7p:UserName stringValue="test"/> 
       <L7p:UserUid stringValue="58916875"/> 
      </L7p:SpecificUser> 
      <L7p:SpecificUser> 
       <L7p:Enabled booleanValue="false"/> 
       <L7p:IdentityProviderOid longValue="-2"/> 
       <L7p:UserLogin stringValue="testengineering-user"/> 
       <L7p:UserName stringValue="testengineering-user"/> 
       <L7p:UserUid stringValue="48201728"/> 
      </L7p:SpecificUser> 
     </wsp:OneOrMore> 
     <wsp:OneOrMore wsp:Usage="Required"> 
      <L7p:HttpRoutingAssertion> 
       <L7p:ProtectedServiceUrl stringValue="http://localhost:13000/Services/Finance/v1"/> 
       <L7p:RequestHeaderRules httpPassthroughRuleSet="included"> 
        <L7p:Rules httpPassthroughRules="included"> 
         <L7p:item httpPassthroughRule="included"> 
          <L7p:Name stringValue="Cookie"/> 
         </L7p:item> 
         <L7p:item httpPassthroughRule="included"> 
          <L7p:Name stringValue="SOAPAction"/> 
         </L7p:item> 
        </L7p:Rules> 
       </L7p:RequestHeaderRules> 
       <L7p:RequestParamRules httpPassthroughRuleSet="included"> 
        <L7p:ForwardAll booleanValue="true"/> 
        <L7p:Rules httpPassthroughRules="included"/> 
       </L7p:RequestParamRules> 
       <L7p:ResponseHeaderRules httpPassthroughRuleSet="included"> 
        <L7p:Rules httpPassthroughRules="included"> 
         <L7p:item httpPassthroughRule="included"> 
          <L7p:Name stringValue="Set-Cookie"/> 
         </L7p:item> 
        </L7p:Rules> 
       </L7p:ResponseHeaderRules> 
      </L7p:HttpRoutingAssertion> 
      <L7p:Include> 
       <L7p:PolicyGuid stringValue="b438384e-eeb0-45c5-8a7e-d30da78f07ee"/> 
      </L7p:Include> 
     </wsp:OneOrMore> 
    </wsp:All> 
</wsp:Policy> 

回答

1

All元素下的唯一CDATA是您修剪的空白。如果您想獲取DOM元素,請使用NODENODESETNodeList)選項。

String xml = "<foo><bar baz='hello' /></foo>"; 
InputSource src = new InputSource(new StringReader(xml)); 
XPathExpression expr = XPathFactory.newInstance().newXPath() 
    .compile("/foo/bar"); 
Node node = (Node) expr.evaluate(src, XPathConstants.NODE); 

Transformer trans = TransformerFactory.newInstance().newTransformer(); 
trans.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes"); 
trans.transform(new DOMSource(node), new StreamResult(System.out)); 
+0

謝謝。您對CDATA的評論讓我工作。雖然嘗試太多東西,但我也簡化了我的xpath查詢,並沒有尋找我最初尋找的實際元素/屬性。我沒有試過你的代碼,並且不明白爲什麼我需要變壓器。 – John

+0

@John - 由於toString()對'Node'類型沒有太大的作用,因此轉換器僅用於在演示代碼中將XML打印到'System.out'中 - 參見[這裏](http:// stackoverflow .COM /問題/ 1219596)。 – McDowell

0

調用評估()的一個參數請求的結果轉換爲一個字符串,即相當於取請求的節點的字符串值:即,所選擇的元素的文本節點的後代的級聯。由於所有的後代文本節點都是空白的,你將不會得到任何回報。

有一次,名稱空間不是問題。