Reputation: 45553
In a java project, consider a file with about 1,000-100,000
xml elements in it. Each xml element needs to be validated with some business rules.
Some of the element nodes are as below:
<transfer>
<bank-id>BIESXXTH</bank-id>
<from-account>016534412</from-account>
<to-account>016534412</to-account>
<amount>765000</amount>
<transaction-time>2015-08-08T13:34:00</transaction-time>
</transfer>
The rules are some thing like:
amounts
should be less than 500000000
from-accounts
should not start with 03
The size of xml file with 1,000
elements is about 400KB
and the size of file with 100,000
elements the file size will be about 40MB
To validate the business rules we can:
I want to know, which one is better (considering performance and memory usage)?!
Also if any one has same experience, may it come the situation that I could not do what I want with xpath !
Upvotes: 2
Views: 373
Reputation: 439
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.
public class Employee {
public String getFirstName(){
...
}
}
Employee emp = new Employee();
JXPathContext context = JXPathContext.newContext(emp);
String fName = (String)context.getValue("firstName");
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:
public class Employee {
public Address getHomeAddress(){
...
}
}
public class Address {
public String getStreetNumber(){
...
}
}
Employee emp = new Employee();
...
JXPathContext context = JXPathContext.newContext(emp);
String sNumber = (String)context.getValue("homeAddress/streetNumber");
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:
Address addr = (Address)context.getValue("homeAddress");
Example 3: Setting Properties
JXPath can be used to modify property values.
public class Employee {
public Address getAddress() {
...
}
public void setAddress(Address address) {
...
}
}
Employee emp = new Employee();
Address addr = new Address();
...
JXPathContext context = JXPathContext.newContext(emp);
context.setValue("address", addr);
context.setValue("address/zipCode", "90190");
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.
public class AddressFactory extends AbstractFactory {
public boolean createObject(JXPathContext context,
Pointer pointer, Object parent, String name, int index){
if ((parent instanceof Employee) && name.equals("address"){
((Employee)parent).setAddress(new Address());
return true;
}
return false;
}
}
JXPathContext context = JXPathContext.newContext(emp);
context.setFactory(new AddressFactory());
context.createPathAndSetValue("address/zipCode", "90190");
Upvotes: 1
Reputation: 1032
File xmlFile = new File(path);
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setFeature(
"http://apache.org/xml/features/nonvalidating/load-external-dtd",
false);
DocumentBuilder builder = factory.newDocumentBuilder();
document = builder.parse(xmlFile); //or parse the String
document.getDocumentElement().normalize();
So now you have the xml file as a Document object.
I'd suggest checking each node as it comes up so you don't have to create objects that potentially won't be added to the list.
List<Transfer> list = new ArrayList<Transfer>();
NodeList nodelist = document.getElementsByTagName("transfer");
for (int i=0; i<nodelist.getLength(); i++) {
Element element = (Element) nodelist.item(i);
if (isValidTransfer(element) {
Transfer t = buildTransferFromElement(element);
list.add(t);
}
}
I'm sure you can work out how to create the isValidTransfer
and buildTransferFromElement
methods.
Give the W3C Javadoc a read as well, it's pretty helpful.
Upvotes: 1