[英]issue parsing xml with namespaces using jdk xpath
I am having difficulty trying to parse an XML content with Xpath. 我在尝试使用Xpath解析XML内容时遇到困难。 Xml includes namespace information.
Xml包含名称空间信息。 I have tried to create a NameSpaceContextImp (apache WS commons implementations of NameSpaceContext interface in jdk) to map the namaspace prefixes to URIs, however couldn't successfully queried the xml document.
我尝试创建一个NameSpaceContextImp(jdk中NameSpaceContext接口的WS WS公共实现)以将namaspace前缀映射到URI,但是无法成功查询xml文档。 When I use online xpath testing tool at http://chris.photobooks.com/xml/default.htm , the xpath query I use comes up with my expected nodes/elements.
当我使用http://chris.photobooks.com/xml/default.htm上的在线xpath测试工具时,我使用的xpath查询包含预期的节点/元素。 So I am trying to figure out what it is that I am doing wrong.
所以我试图弄清楚我做错了什么。 I am providing the xml document and the sample code snippet.
我正在提供xml文档和示例代码片段。 I would appreciate any feedback.
我将不胜感激任何反馈。 As a note, I have tried xpath queries both with and without the namespace prefixes.
注意,我尝试了带有和不带有名称空间前缀的xpath查询。
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>
The only CDATA under the All
element is whitespace, which you trim. All
元素下唯一的CDATA是空白,您可以对其进行裁剪。 If you want to get DOM elements, use the NODE or NODESET ( NodeList
) options. 如果要获取DOM元素,请使用NODE或NODESET (
NodeList
)选项。
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));
Calling evaluate() with one argument requests conversion of the result to a string, which is equivalent to taking the string value of the requested node: that is, the concatenation of the text node descendants of the selected element. 使用一个参数调用Evaluate()要求将结果转换为字符串,这等效于获取所请求节点的字符串值:即所选元素的文本节点后代的串联。 Since all the descendant text nodes are whitespace, you will get nothing back.
由于所有后代文本节点都是空格,因此您将一无所获。
For once, namespaces are not the issue. 一次,名称空间不是问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.