I have a task to parse an XML file with JDom in Eclipse. When I started to create the code, my code is only sufficient to get the length(how many) node with Tag name model. The task is more specific, I need to get the length of the node with tag name model which has attribute type. How should I modify my code to get the result?
This is part of my XML file
<container>
<models>
<model id="FM1" type="BoQ">
<meta
<phase phaseDesc="PRCR>SLCT>"/>
<domain domainCode="SPM.BOQ.RFP "/>
<levelOfDetail levelOfDetailCode="[4]"/>
</meta>
</model>
<model id="FM2" type="Object">
<meta>
<phase phaseDesc="PRCR>SLCT> "/>
<domain domainCode="BIM"/>
<levelOfDetail levelOfDetailCode="[4] "/>
</meta>
</model>
<model id="FM3">
<meta>
<phase phaseDesc="PRCR>SLCT>"/>
<domain domainCode="SPM.QTO"/>
<levelOfDetail levelOfDetailCode="[5]"/>
</meta>
</model>
<model id="FM4" type="BoQ">
<meta>
<phase phaseDesc="PRCR>SLCT>"/>
<domain domainCode="TSM.TSC"/>
<levelOfDetail levelOfDetailCode="[3]"/>
</meta>
</model>
</models>
<linkModels>
<linkModel id="LM1" type="QuantitySplit">
<meta>
<info>
<i k="ModelName" v="Linkmodell"/>
</info>
<domain domainCode="LKM.QSP" domainDesc="Link Model"/>
</meta>
<models>
<model id="FM1"/>
<model id="FM2"/>
<model id="FM3"/>
<model id="FM4"/>
</models>
</container>
public class xmldom {
public static void main(String[] args) {
Document xmlDoc = getDocument("./src/MMT_Angebot_Anfrage.xml");
System.out.println("Root: "+
xmlDoc.getDocumentElement().getNodeName());
NodeList model = xmlDoc.getElementsByTagName("model");
System.out.println("Number of Models " +
model.getLength());
String elementPhase = "phase";
String elementDomain = "domain";
String elementLOD = "levelOfDetail";
String attrPhase = "phaseCode";
String attrDomain = "domainCode";
String attrLOD = "levelOfDetailCode";
getElementAndAttrib(model, elementPhase, elementDomain, elementLOD, attrPhase, attrDomain, attrLOD);
}
private static Document getDocument(String docString) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setIgnoringComments(true);
factory.setIgnoringElementContentWhitespace(true);
factory.setValidating(true);
DocumentBuilder builder = factory.newDocumentBuilder();
return builder.parse(new InputSource(docString));
}
catch(Exception ex) {
System.out.println(ex.getMessage());
}
return null;
}
private static void getElementAndAttrib(NodeList model,
String elementPhase, String elementDomain, String elementLOD,
String attrPhase, String attrDomain, String attrLOD) {
try {
for(int i=0; i < model.getLength(); i++){
Node modelNode = model.item(i);
Element modelElement = (Element)modelNode;
NodeList phaseList = modelElement.getElementsByTagName(elementPhase);
NodeList domainList = modelElement.getElementsByTagName(elementDomain);
NodeList lodList = modelElement.getElementsByTagName(elementLOD);
Element phaseElement = (Element)phaseList.item(0);
Element domainElement = (Element)domainList.item(0);
Element lodElement = (Element)lodList.item(0);
NodeList elementList = phaseElement.getChildNodes();
System.out.println("=================================================");
System.out.println(attrPhase + " : "+ phaseElement.getAttribute(attrPhase));
System.out.println(attrDomain + " : "+ domainElement.getAttribute(attrDomain));
System.out.println(attrLOD + " : "+ lodElement.getAttribute(attrLOD));
}
}
catch(Exception ex) {
System.out.println(ex.getMessage());
}
}
}
You want to count the number of <model> elements that contains the type attribute? If, so XPath is the most suitable tool.
XPath xp = XPathFactory.newInstance().newXPath();
Double num = xp.evaluate("count(//model[#type])", doc, XPathConstants.NUMBER);
Btw, you are using DOM, not JDOM.
Related
<DistinctParty FixedRef="10569">
<Comment />
<Profile ID="10569" PartySubTypeID="4">
<Identity ID="952" FixedRef="10569" Primary="true" False="false">
<Alias FixedRef="10569" AliasTypeID="1403" Primary="true" LowQuality="false">
<DocumentedName ID="952" FixedRef="10569" DocNameStatusID="1">
<DocumentedNamePart>
<NamePartValue NamePartGroupID="36916" ScriptID="215" ScriptStatusID="1" Acronym="false">MAKHLUF</NamePartValue>
</DocumentedNamePart>
<DocumentedNamePart>
<NamePartValue NamePartGroupID="36917" ScriptID="215" ScriptStatusID="1" Acronym="false">Hafiz</NamePartValue>
</DocumentedNamePart>
</DocumentedName>
</Alias>
<Alias FixedRef="10569" AliasTypeID="1400" Primary="false" LowQuality="false">
<DocumentedName ID="12197" FixedRef="10569" DocNameStatusID="2">
<DocumentedNamePart>
<NamePartValue NamePartGroupID="18042" ScriptID="215" ScriptStatusID="1" Acronym="false">MAKHLOUF</NamePartValue>
</DocumentedNamePart>
<DocumentedNamePart>
<NamePartValue NamePartGroupID="18043" ScriptID="215" ScriptStatusID="1" Acronym="false">Hafez</NamePartValue>
</DocumentedNamePart>
</DocumentedName>
</Alias>
<NamePartGroups>
<MasterNamePartGroup>
<NamePartGroup ID="36916" NamePartTypeID="1520" />
</MasterNamePartGroup>
<MasterNamePartGroup>
<NamePartGroup ID="36917" NamePartTypeID="1521" />
</MasterNamePartGroup>
<MasterNamePartGroup>
<NamePartGroup ID="18042" NamePartTypeID="1520" />
</MasterNamePartGroup>
<MasterNamePartGroup>
<NamePartGroup ID="18043" NamePartTypeID="1521" />
</MasterNamePartGroup>
</NamePartGroups>
</Identity>
<Feature ID="5887" FeatureTypeID="8">
<FeatureVersion ID="570" ReliabilityID="1">
<Comment />
<DatePeriod CalendarTypeID="1" YearFixed="false" MonthFixed="false" DayFixed="false">
<Start Approximate="true" YearFixed="false" MonthFixed="false" DayFixed="false">
<From>
<Year>1975</Year>
<Month>1</Month>
<Day>1</Day>
</From>
<To>
<Year>1975</Year>
<Month>1</Month>
<Day>1</Day>
</To>
</Start>
<End Approximate="true" YearFixed="false" MonthFixed="false" DayFixed="false">
<From>
<Year>1975</Year>
<Month>12</Month>
<Day>31</Day>
</From>
<To>
<Year>1975</Year>
<Month>12</Month>
<Day>31</Day>
</To>
</End>
</DatePeriod>
<VersionDetail DetailTypeID="1430" />
</FeatureVersion>
<IdentityReference IdentityID="952" IdentityFeatureLinkTypeID="1" />
</Feature>
<Feature ID="5888" FeatureTypeID="9">
<FeatureVersion ID="571" ReliabilityID="1">
<Comment />
<VersionDetail DetailTypeID="1432">Damascus, Syria</VersionDetail>
</FeatureVersion>
<IdentityReference IdentityID="952" IdentityFeatureLinkTypeID="1" />
</Feature>
<Feature ID="164625" FeatureTypeID="25">
<FeatureVersion ID="214625" ReliabilityID="1">
<Comment />
<VersionLocation LocationID="14625" />
</FeatureVersion>
<IdentityReference IdentityID="952" IdentityFeatureLinkTypeID="1" />
</Feature>
<Feature ID="310569" FeatureTypeID="26">
<FeatureVersion ID="410569" ReliabilityID="1">
<Comment />
<VersionDetail DetailTypeID="1432">Colonel</VersionDetail>
</FeatureVersion>
<IdentityReference IdentityID="952" IdentityFeatureLinkTypeID="1" />
</Feature>
</Profile>
</DistinctParty>
This is an XML and its root is DistinctParty, now I need to extract two tags from it via JAVA.
NamePartyValue
VersionDetail
Now I get the root element and can extract NamePartyValue with these methods, but I also need to extract VersionDetail element which I can't even find in the result, could you please direct me in an accurate direction.
public NodeList readXMLFileUpdated(String path) {
File fXmlFile = new File(path);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = null;
Document doc = null;
NodeList nList = null;
try {
dBuilder = dbFactory.newDocumentBuilder();
doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
nList = doc.getElementsByTagName("DistinctParty");
} catch (Exception e) {
e.printStackTrace();
}
return nList;
}
public List<Company> getCompanyNamesXML(NodeList nodes){
List<Company> listOfCompanies = new ArrayList<>();
for(int i = 0; i<nodes.getLength(); i++)
listOfCompanies.add(new Company(nodes.item(i).getTextContent()));
return listOfCompanies;
}
This statement nodes.item(i).getTextContent() in upper method returns me the value of NamePartyValue field and when trying to get children of this node with this nodes.item(i).getChildNodes() I can't see VersionDetail in the result, any idea what I might be missing?
Just like you found the NodeList of "DistincyParty" by calling doc.getElementsByTagName(), you can find VersionDetail or NamePartValue elements by doing the same thing.
1.This is my example file "example.xml"
<?xml version="1.0" encoding="UTF-8"?>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
<DATA>
2.This is my java code that parses the file "example.xml" :
public static void main(String argv[]) {
try {
Properties prop = System.getProperties();
File file = new File("E:/workspace/example.xml");
DocumentBuilderFactory dbildfactory =DocumentBuilderFactory.newInstance();
DocumentBuilder dbild = dbildfactory.newDocumentBuilder();
Document doc = dbild.parse(file);
doc.getDocumentElement().normalize();
NodeList nodeL = doc.getElementsByTagName("ALL");
for (int s = 0; s < nodeL.getLength(); s++) {
Node nodde = nodeL.item(s);
if (nodde.getNodeType() == Node.ELEMENT_NODE){
Element fstElmnt = (Element) nodde;
NodeList list = fstElmnt.getElementsByTagName("MARKE");
Element disp = (Element) list.item(0);
NodeList dispmarke = disp.getChildNodes();
System.out.println("<MARKE>" + ((Node)
dispmarke.item(0)).getNodeValue() + "</MARKE>");
String dispbrd = prop.getProperty("prop4");
((Node) dispmarke.item(0)).setNodeValue(dispbrd);
System.out.println("<MARKE>" + ((Node)
dispmarke.item(0)).getNodeValue() + "</MARKE>");
if(dispmarke.item(0).getNodeValue().equals("LEX") ){
NodeList nod = fstElmnt.getElementsByTagName("MARKE");
Element element = (Element) nod.item(0);
NodeList mod = element.getChildNodes();
System.out.println("<MARKE>" + ((Node) mod.item(0)).getNodeValue() + "</MARKE>");
prop.put("norm", "X300");
((Node) mod.item(0)).setNodeValue(prop.getProperty("norm"));
System.out.println("<MARKE>" + ((Node) mod.item(0)).getNodeValue() + "</MARKE>");
}
}
}
TransformerFactory transformerFactory =
TransformerFactory.newInstance();
Transformer transformer =
transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
DOMSource source = new DOMSource(doc);
StreamResult console = new StreamResult(System.out);
StreamResult fil = new StreamResult(new File("E:/workspace/res/output.xml"));
transformer.transform(source, console);
transformer.transform(source, fil);
}
catch (Exception e) {
e.printStackTrace();
}
}
3.At this time, the nodes are saved to a new file "output.xml":
<?xml version="1.0" encoding="UTF-8"?>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
<DATA>
</ALL>
4.I would like that, there were several copies of nodes in file output.xml.
Everyone this node started after the last node:
<?xml version="1.0" encoding="UTF-8"?>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
<DATA>
</ALL>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
<DATA>
</ALL>
...
5.How can the easiest way to do this in Java? What loops used for this?
I had to fix your input XML to have a root element:
<?xml version="1.0" encoding="UTF-8"?>
<ROOT>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
</DATA>
</ROOT>
Then I could use XMLBeam (A data projection library, DISCLOSURE: I'm affiliated with this project) to
read the input,
wrap it into an ALL Element
duplicate the input and
print it out
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;
import org.xmlbeam.XBProjector;
import org.xmlbeam.XBProjector.Flags;
import org.xmlbeam.annotation.XBWrite;
import org.xmlbeam.dom.DOMAccess;
#SuppressWarnings("javadoc")
public class DuplicateNode {
// Projection to embed some nodes into an "ALL" element
public interface AllNodes {
#XBWrite("./*")
AllNodes setNodes(List<DOMAccess> nodes);
};
// Projection for the output document
public interface OutputProjection {
#XBWrite("/ROOT/*")
void setNodes(List<AllNodes> nodes);
};
public static void main(String[] args) throws IOException {
// Create the projector we will use to project the data
XBProjector projector = new XBProjector(Flags.TO_STRING_RENDERS_XML);
//Read all nodes from input document
List<DOMAccess> nodes =projector.io().url("res://example.xml").evalXPath("/ROOT/*").asListOf(DOMAccess.class);
// Create some copies
List<AllNodes> newNodeList = new LinkedList<AllNodes>();
newNodeList.add(projector.projectEmptyElement("ALL",AllNodes.class).setNodes(nodes));
newNodeList.add(projector.projectEmptyElement("ALL",AllNodes.class).setNodes(nodes));
//...
// Create an output projection that will take the copied nodes
OutputProjection outputProjection = projector.projectEmptyDocument(OutputProjection.class);
// set nodes to the output projection
outputProjection.setNodes(newNodeList);
// print it out (or write to file, stream,...)
System.out.println(outputProjection);
}
}
This program prints out:
<ROOT>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
</DATA>
</ALL>
<ALL>
<VER>7.0</VER>
<NATIONALITY>FIN</NATIONALITY>
<DATA>
<USER>ED</USER>
<PLZ>XXX</PLZ>
<BEGIN>2015-05-16</BEGIN>
<CURRENCY>90</CURRENCY>
<MARKE>KIA</MARKE>
</DATA>
</ALL>
</ROOT>
Consider the example:
<PARAMETER FIELD="QUERYSTORE_TYPE" LABEL="Query Type" NAME="QUERYSTORE" NUM_ROW="40">
<DEFAULT>""</DEFAULT>
</PARAMETER>
<PARAMETER FIELD="GUESS_SCHEMA" LABEL="Guess Schema" NAME="GUESS_SCHEMA" NUM_ROW="40">
<DEFAULT></DEFAULT>
</PARAMETER>
<PARAMETER FIELD="MEMO_SQL" LABEL="Query" NAME="QUERY" NUM_ROW="45" REQUIRED="true">
<DEFAULT>"select id, name from employee"</DEFAULT>
</PARAMETER>
Now I have to remove all double quotes in content of DEFAULT tag. I tried doing the following
NodeList nList = doc.getElementsByTagName("PARAMETER");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
NodeList nl = nNode.getChildNodes();
for (int k = 0; k < nl.getLength(); k++) {
if (nl.item(k).getNodeName().equals("DEFAULT")) {
nl.item(k).setTextContent(nl.item(k).getTextContent().replaceAll("\"", ""));
}
}
}
}
But its not working. When I open the XML file it still contains those double quotes. How do i do this?
And also wherever there is double quote, I have to add another attribute to PARAMETER element namely encode with value indicating if there was a double quote in DEFAULT tag. i.e.
<PARAMETER FIELD="QUERYSTORE_TYPE" LABEL="Query Type" NAME="QUERYSTORE" NUM_ROW="40" encode ="true">
<DEFAULT></DEFAULT>
</PARAMETER>
<PARAMETER FIELD="GUESS_SCHEMA" LABEL="Guess Schema" NAME="GUESS_SCHEMA" NUM_ROW="40" encode = "false">
<DEFAULT></DEFAULT>
</PARAMETER>
<PARAMETER FIELD="MEMO_SQL" LABEL="Query" NAME="QUERY" NUM_ROW="45" REQUIRED="true" encode="true">
<DEFAULT>select id, name from employee</DEFAULT>
</PARAMETER>
How do I do this?
There is nothing wrong with your code. Did you try to overwrite the file or did you write out to a new file?
foo.xml
<PARAMETERS>
<PARAMETER FIELD="QUERYSTORE_TYPE" LABEL="Query Type" NAME="QUERYSTORE"
NUM_ROW="40">
<DEFAULT>""</DEFAULT>
</PARAMETER>
<PARAMETER FIELD="GUESS_SCHEMA" LABEL="Guess Schema" NAME="GUESS_SCHEMA"
NUM_ROW="40">
<DEFAULT></DEFAULT>
</PARAMETER>
<PARAMETER FIELD="MEMO_SQL" LABEL="Query" NAME="QUERY"
NUM_ROW="45" REQUIRED="true">
<DEFAULT>"select id, name from employee"</DEFAULT>
</PARAMETER>
</PARAMETERS>
XmlUnquoteExample.java
import java.io.*;
import javax.xml.parsers.*;
import javax.xml.transform.*;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import org.xml.sax.SAXException;
public class XmlUnquoteExample {
public static void main(String[] args) {
Document doc;
try {
doc = readXmlFile("resources/foo.xml");
System.out.println("<!-- BEFORE -->");
printDocument(doc, System.out);
removeQuotes(doc);
System.out.println("<!-- AFTER -->");
printDocument(doc, System.out);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Document readXmlFile(String filename)
throws ParserConfigurationException, SAXException, IOException {
InputStream is;
DocumentBuilderFactory factory;
DocumentBuilder builder;
is = ClassLoader.getSystemResourceAsStream(filename);
factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
builder = factory.newDocumentBuilder();
return builder.parse(new ByteArrayInputStream(toByteArray(is, 16384)));
}
public static byte[] toByteArray(InputStream is, int bufferSize) throws IOException {
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
int nRead;
byte[] data = new byte[bufferSize];
while ((nRead = is.read(data, 0, data.length)) != -1) {
buffer.write(data, 0, nRead);
}
buffer.flush();
return buffer.toByteArray();
}
public static void printDocument(Document doc, OutputStream out)
throws IOException, TransformerException {
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer = tf.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no");
transformer.setOutputProperty(OutputKeys.METHOD, "xml");
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "4");
transformer.transform(new DOMSource(doc), new StreamResult(
new OutputStreamWriter(out, "UTF-8")));
}
public static void removeQuotes(Document doc) {
NodeList nList = doc.getElementsByTagName("PARAMETER");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = (Node) nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
NodeList nl = nNode.getChildNodes();
for (int k = 0; k < nl.getLength(); k++) {
if (nl.item(k).getNodeName().equals("DEFAULT")) {
nl.item(k).setTextContent(
nl.item(k).getTextContent()
.replaceAll("\"", ""));
}
}
}
}
}
}
Output
<!-- BEFORE -->
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PARAMETERS>
<PARAMETER FIELD="QUERYSTORE_TYPE" LABEL="Query Type" NAME="QUERYSTORE" NUM_ROW="40">
<DEFAULT>""</DEFAULT>
</PARAMETER>
<PARAMETER FIELD="GUESS_SCHEMA" LABEL="Guess Schema" NAME="GUESS_SCHEMA" NUM_ROW="40">
<DEFAULT/>
</PARAMETER>
<PARAMETER FIELD="MEMO_SQL" LABEL="Query" NAME="QUERY" NUM_ROW="45" REQUIRED="true">
<DEFAULT>"select id, name from employee"</DEFAULT>
</PARAMETER>
</PARAMETERS>
<!-- AFTER -->
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<PARAMETERS>
<PARAMETER FIELD="QUERYSTORE_TYPE" LABEL="Query Type" NAME="QUERYSTORE" NUM_ROW="40">
<DEFAULT/>
</PARAMETER>
<PARAMETER FIELD="GUESS_SCHEMA" LABEL="Guess Schema" NAME="GUESS_SCHEMA" NUM_ROW="40">
<DEFAULT/>
</PARAMETER>
<PARAMETER FIELD="MEMO_SQL" LABEL="Query" NAME="QUERY" NUM_ROW="45" REQUIRED="true">
<DEFAULT>select id, name from employee</DEFAULT>
</PARAMETER>
</PARAMETERS>
Could it be that you don't write the modified document to some output file? Here's how:
TransformerFactory trf = TransformerFactory.newInstance();
Transformer transformer = trf.newTransformer();
StreamResult result = new StreamResult(new FileOutputStream( "upd.xml" ));
DOMSource source = new DOMSource( document );
transformer.transform(source, result);
For the second question, keep track of quotes being present and add the attribute:
Boolean quotes = false;
for( int k = 0; k < nl.getLength(); k++ ){
String txt = nl.item(k).getTextContent();
if( txt.indexOf('"') >= 0 ){
quotes = true;
}
// ...
}
eElement.setAttribute("encode", quotes.toString() );
You already have a working answer, but I like to show a shorter solution using XMLBeam:
public class RemoveDoubleQuotes {
public interface Projection {
public interface Subprojection {
#XBRead(".")
String getValue();
#XBWrite(".")
void setValue(String value);
}
#XBRead("//DEFAULT")
List<Subprojection> getAllDefaults();
}
public static void main(final String[] args) throws IOException {
Projection projection = new XBProjector(Flags.TO_STRING_RENDERS_XML).io().url("resource://test.xml").read(Projection.class);
for (Subprojection s : projection.getAllDefaults()) {
s.setValue(s.getValue().replaceAll(Pattern.quote("\""), ""));
}
System.out.println(projection.toString());
}
}
This program prints out the same result with much less lines of code.
<?xml version="1.0" encoding="UTF-8"?>
<Root xmlns:tns="http://www.example.org/book" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.example.org/book test.xsd ">
<Class name="AirwayBill">
<Attribute name="billNo" primary="true" />
<Attribute name="date" primary="false" />
<Attribute name="shipper" primary="false" class="Person" />
</Class>
<Class name="Person">
<Attribute name="perId" primary="true" />
<Attribute name="fname" primary="false" />
<Attribute name="lname" primary="false" />
</Class>
</Root>
I want to read attribute value of attribute "name" of Tag in which attribute "class" is present.. how do i do that? i am using javax.xml.parsers.DocumentBuilder and javax.xml.parsers.DocumentBuilderFactory classes to parse and read the xml file.
Probably there is a better way to do it, but this works:
public static void parseXml(){
File fXmlFile = new File("c://test.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder;
try {
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
Element root = doc.getDocumentElement();
NodeList childList = root.getElementsByTagName("Class");
for (int i = 0; i<childList.getLength(); i++){
System.out.println("Class: " + childList.item(i).getAttributes().getNamedItem("name").getNodeValue());
NodeList attList = ((Element)childList.item(i)).getElementsByTagName("Attribute");
for (int j = 0; j<attList.getLength(); j++){
System.out.print(" Att: " + attList.item(j).getAttributes().getNamedItem("name").getNodeValue());
System.out.println(" primary " + attList.item(j).getAttributes().getNamedItem("primary").getNodeValue());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
How to convert List of Object to XML doc using XStream ?
and how to deserialize it back ?
This is my xml
<?xml version="1.0" encoding="UTF-8"?>
<persons>
<person>
<fullname>Guilherme</fullname>
<age>10</age>
<address>address,address,address,address,</address>
</person>
<person>
<fullname>Guilherme</fullname>
<age>10</age>
<address>address,address,address,address,</address>
</person>
</persons>
Person bean contains 3 fields how to convert back it to Bean List using custom converters ?
You don't necessarily need a CustomConverter.
You need a class to hold your list:
public class PersonList {
private List<Person> list;
public PersonList(){
list = new ArrayList<Person>();
}
public void add(Person p){
list.add(p);
}
}
To serialise the list to XML:
XStream xstream = new XStream();
xstream.alias("person", Person.class);
xstream.alias("persons", PersonList.class);
xstream.addImplicitCollection(PersonList.class, "list");
PersonList list = new PersonList();
list.add(new Person("ABC",12,"address"));
list.add(new Person("XYZ",20,"address2"));
String xml = xstream.toXML(list);
To deserialise xml to a list of person objects:
String xml = "<persons><person>...</person></persons>";
PersonList pList = (PersonList)xstream.fromXML(xml);
Just use the std toXml and fromXml methods, see http://en.wikipedia.org/wiki/XStream for an example. Also see http://x-stream.github.io/converters.html on how the default conversions work.
OK, so the default converters won't quite work in your case. You need to follow:
http://x-stream.github.io/converter-tutorial.html
Load XML
public static Object Load(String xmlPath) throws Exception
{
File FileIn = new File(xmlPath);
if(FileIn.exists()) {
//Initialise Doc
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document Doc = builder.parse(FileIn);
//Initialise XPath
XPathFactory xPathFactory = XPathFactory.newInstance();
XPath xpath = xPathFactory.newXPath();
String objectClassLocation = xpath.evaluate("/object/#class",Doc);
Object ObjType;
//Create List of attributes for the Student
XPathExpression xpathExpression = xpath.compile("/object/*");
NodeList ObjTypeAttributes = (NodeList)xpathExpression.evaluate(Doc, XPathConstants.NODESET);
ObjType = CreateObject(ObjTypeAttributes, objectClassLocation);
return ObjType;
}
return null;
}
Create Object
public static Object CreateObject(NodeList ObjectAttributes, String Location) throws Exception
{
Class ClassName = Class.forName(Location);
Object object = ClassName.newInstance();
Field[] fields = ClassName.getFields();
for(int x = 0; x < fields.length;x++)
{
for(int y = 0; y<ObjectAttributes.getLength(); y++)
{
if(!(ObjectAttributes.item(y) instanceof Text)) {
String check = ObjectAttributes.item(y).getAttributes().item(0).getNodeValue();
if(fields[x].getName().equals(check))
{
Field curField = ClassName.getField(fields[x].getName());
if(ObjectAttributes.item(y).getAttributes().getLength() < 2) {
curField.set(object,CreateList(ObjectAttributes.item(y).getChildNodes()));
}
else {
curField.set(object,ObjectAttributes.item(y).getAttributes().item(1).getNodeValue());
}
}
}
}
}
return object;
}
Create list (Only used if xml has an object of objects)
public static ArrayList CreateList(NodeList ArrayNodeList) throws Exception
{
ArrayList List = new ArrayList();
for(int x = 0; x < ArrayNodeList.getLength();x++)
{
if(!(ArrayNodeList.item(x) instanceof Text)) {
Node curNode = ArrayNodeList.item(x);
NodeList att = curNode.getChildNodes();
String Location = ArrayNodeList.item(x).getAttributes().item(0).getNodeValue();
Object newOne = CreateObject(att, Location);
List.add(newOne);
}
}
return List;
}
XML example I used
<?xml version="1.0" encoding="UTF-8"?>
<object class="Example.Rps">
<field name="Representatives">
<object class="Example.Rep">
<field name="RepID" value="888225462"/>
<field name="Surname" value="Johnson"/>
<field name="Name" value="Dave"/>
<field name="Clients">
<object class="Example.Client">
<field name="ClientName" value="Cipla"/>
<field name="State" value="New York"/>
<field name="grade" value="A"/>
</object>
<object class="Example.Client">
<field name="ClientName" value="Pharmco"/>
<field name="State" value="Iowa"/>
<field name="grade" value="B"/>
</object>
</field>
</object>
<object class="Example.Rep">
<field name="RepID" value="888225462"/>
<field name="Surname" value="Dickson"/>
<field name="Name" value="Ben"/>
<field name="Clients">
<object class="Example.Client">
<field name="ClientName" value="XYZ"/>
<field name="State" value="New Mexico"/>
<field name="grade" value="A"/>
</object>
<object class="Example.Client">
<field name="ClientName" value="Pharmco"/>
<field name="State" value="Ohio"/>
<field name="grade" value="c"/>
</object>
</field>
</object>
</field>
</object>