I've got the following XML:
<?xml version="1.0" encoding="UTF-8"?>
<CreateReservation>
<NewReservation>
<Profile op="D">
<ProfileID>ID</ProfileID>
<ProfileType>TYPE</ProfileType>
</Profile>
<Number>123456</Number>
</NewReservation>
marshalled with JAXB from CreateReservation class in the following way:
CreateReservation request = new CreateReservation("123456", "D");
String xpathExpr = "boolean(//*[local-name()='CreateReservationRQ']//@op='D')"
JAXBContext context = JAXBContext.newInstance(CreateReservation.class);
marshaller = context.createMarshaller();
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
Document document = db.newDocument();
marshaller.marshal(request, document); //line creates xml presented above
//EVALUATION
XPath xPath = XPathFactory.newInstance().newXPath();
xPath.evaluate(xpathExpr, document, XPathConstants.BOOLEAN); //line evaluates xpath and returns true
Summing everythig up, presented code marshalls CreateReservation class, create corresponding XML out of it, and with xpath expression checks if created xml has any <CreateReservation> node, which has any child with op="D" attribute. The check is done with the following xpath expression:
boolean(//*[local-name()='CreateReservationRQ']//@op='D')
The condition works fine, fot presented code sample. Right now I would like to get rid of unnecessary marshalling of CreateReservation class. To do so, I would like to switch from JAXB to JXPath:
PathContext jXPathContext = JXPathContext.newContext(obj);
Object obj = jXPathContext.getValue(CONDITION);
if (obj != null) {
//code should behave exactly the same, as my previous model
}
obj- member of CreateReservation class (it's structure is exactly the same as presented in xml above)
CONDITION- my JXPath query
The idea is, that line:
Object obj = jXPathContext.getValue(CONDITION);
Returns any node, when CreateREservation class has op field equal to 'D'. If no node is present null is returned. Functionally code should behave exactly the same as previously. Could you tell me how my CONDITION should look like?
For dynamic xpath to object implementation you can have a look into this.
Example 1: JavaBean Property Access
JXPath can be used to access properties of a JavaBean.
In this example, we are using JXPath to access a property of the emp bean. In this simple case the invocation of JXPath is equivalent to invocation of getFirstName() on the bean.
Example 2: Nested Bean Property Access
JXPath can traverse object graphs:
In this case XPath is used to access a property of a nested bean. A property identified by the xpath does not have to be a "leaf" property. For instance, we can extract the whole Address object in above example:
Example 3: Setting Properties
JXPath can be used to modify property values.
Example 4: Creating objects JXPath can be used to create new objects. First, create a subclass of AbstractFactory and install it on the JXPathContext. Then call createPathAndSetValue() instead of "setValue". JXPathContext will invoke your AbstractFactory when it discovers that an intermediate node of the path is null. It will not override existing nodes.
For detail help look into this link: JxPath Tutorial