Я знаю, что что-то похожее на этот вопрос задавали (и отвечали) несколько раз, и я пробовал много предложений, но по какой-то причине я не могу заставить эту работу работать.Простой способ получить выполнение Xpath против строки в Java?
У меня есть XML-документ (в составной составной строке) в переменной String, и я хочу выполнить поиск по Xpath в этом документе XML и получить результат (ы) из этого поиска в Xpath.
Как я могу это сделать?
Вот один пример того, что я пытался (или на самом деле слияния нескольких различных вещей, которые я нашел:.
// From: http://javarevisited.blogspot.com/2012/12/create-and-evaluate-xpath-java-example-tutorial-program.html
//Create DocumentBuilderFactory for reading xml file
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputStream inputStream = new ByteArrayInputStream(compositeBodyLine.getBytes());
org.w3c.dom.Document doc = builder.parse(inputStream);
System.out.println("doc.getParentNode()=[" + doc.getParentNode().toString() + "]");
// Create XPathFactory for creating XPath Object
XPathFactory xPathFactory = XPathFactory.newInstance();
// Create XPath object from XPathFactory
XPath xpath = xPathFactory.newXPath();
// Compile the XPath expression for getting all brands
XPathExpression xPathExpr = xpath.compile("/soapEnv:Envelope");
// XPath text example : executing xpath expression in java
Object result = xPathExpr.evaluate(doc, XPathConstants.NODESET);
System.out.println("Java Xpath text example: All brands of popular smartphones ");
printXpathResult(result);
.
.
.
.
public static org.w3c.dom.Document loadXMLFromString(String xml) throws Exception
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader(xml));
return builder.parse(is);
}
Когда я пытаюсь выше код, я получаю нулевой возвращения я думаю, что большинство из примеры, на которые я смотрел, берут файл в качестве входных данных, тогда как в моем случае у меня есть XML-документ в переменной String, поэтому, если бы я должен был догадаться, я бы предположил, что у меня возникают проблемы с вводом XML-данных.
Может ли кто-нибудь предоставить простой способ для этого?
Спасибо, Jim
EDIT: Вот пример входного XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soapenv:Body>
<Request xmlns:xacml-context="urn:oasis:names:tc:xacml:2.0:context:schema:os" xmlns:ns9="urn:oasis:xacml:2.0:saml:assertion:schema:os" xmlns:ns8="urn:oasis:xacml:2.0:saml:protocol:schema:os" xmlns:ns7="http://security.bea.com/ssmws/ssm-soap-types-1.0.xsd" xmlns:ns6="http://www.w3.org/2001/04/xmlenc#" xmlns:ns5="urn:oasis:names:tc:xacml:2.0:policy:schema:os" xmlns:ns4="urn:oasis:names:tc:xacml:2.0:context:schema:os" xmlns:ns3="urn:oasis:names:tc:SAML:2.0:protocol" xmlns:ns2="http://www.w3.org/2000/09/xmldsig#" xmlns="urn:oasis:names:tc:xacml:2.0:context:schema:os">
<Subject>
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://security.bea.com/ssmws/ssm-ws-1.0.wsdl#OESPrincipalInfo">
<AttributeValue>{name=jimXXXX1234}+(class=weblogic.security.principal.WLSUserImpl)</AttributeValue>
</Attribute>
<!-- FOLLOWING IS **THE** GOOD WAY AND DOES WORK WITH OES FOR ROLE -->
<Attribute AttributeId="http://oracle.com/symbols/oes/attribute/group-assertion" DataType="http://security.bea.com/ssmws/ssm-ws-1.0.wsdl#OESPrincipalInfo" xsi:type="ns1:AttributeType">
<AttributeValue xsi:type="ns1:AttributeValueType">{name=Operators}+(class=weblogic.security.principal.WLSGroupImpl)</AttributeValue>
</Attribute>
</Subject>
<Resource>
<Attribute AttributeId="urn:oasis:names:tc:xacml:2.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string">
<AttributeValue>foo/foo1/foo2</AttributeValue>
</Attribute>
</Resource>
<Action>
<Attribute AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string">
<AttributeValue>GET</AttributeValue>
</Attribute>
</Action>
<ns4:Environment xsi:type="ns4:EnvironmentType"
xmlns:ns4="urn:oasis:names:tc:xacml:2.0:context:schema:os"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns4:Attribute AttributeId="http://security.bea.com/ssmws/ssm-ws-1.0.wsdl#RegisteredAttribute"
DataType="http://www.w3.org/2001/XMLSchema#string" xsi:type="ns4:AttributeType">
<ns4:AttributeValue xsi:type="ns4:AttributeValueType">4444444444yes</ns4:AttributeValue>
</ns4:Attribute>
<ns4:Attribute AttributeId="http://security.bea.com/ssmws/ssm-ws-1.0.wsdl#NumberOfBorrowedBooksAttribute"
DataType="http://www.w3.org/2001/XMLSchema#string" xsi:type="ns4:AttributeType">
<ns4:AttributeValue xsi:type="ns4:AttributeValueType">abc</ns4:AttributeValue>
</ns4:Attribute>
</ns4:Environment>
</Request>
</soapenv:Body>
</soapenv:Envelope>
Не используйте 'String.getBytes()', чтобы послать массив байтов в DOM парсер. Сама строка: 'builder.parse (новый InputSource (новый StringReader (compositeBodyLine))). --- У вас есть 'loadXMLFromString()' метод, делающий это таким образом, так почему бы вам не использовать его ???? – Andreas
Ваше выражение XPath использует префикс пространства имен ('soapEnv:'), но * 1) * вы не определили этот префикс (вызовите 'xpath.setNamespaceContext (...)', чтобы исправить это) и * 2) * вы не проанализировали документ с включенным пространством имен (вызовите 'factory.setNamespaceAware (true)', чтобы исправить это). --- Кроме того, как вы ожидаете от нас помощи, когда мы не знаем, как выглядит XML? – Andreas
Andreas - Я добавил XML-пример в исходный msg. Также я попробовал ваше предложение о builder.parse (новый InputSource (новый StringReader (compositeBodyLine))), но тогда я получаю исключение NullPointerException. – user555303