I am receiving a xml payload from a web service call and it is assigned in a String. This xml has 10 elements and I need to change the value of logtime to whatever I want. Since this is a String, is there a way to change any of the element's value.
This is my first java code please let me know if you need more explanation.
code
String xml = dto.getAuditTrail();
Xml
I want to know how can I suppose change the time value of logtime to another format, since this entire xml is a String?
Please help because I am new to it.
Thanks
You need to parse your String in order to obtain a Document object which you can read by tag.
Here you can find how to parse your string, then with Document object you're able to read specific tag:
public void readDocument(Document doc) {
try{
NodeList nList = doc.getElementsByTagName("Event");
System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("\nCurrent Element :" + nNode.getNodeName());
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println("LogTime : " + eElement.getElementsByTagName("logTime").item(0).getTextContent());
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
Source here
This is basic way for xml reading, but you can directly edit the xml too:
public void editDocument() {
try{
NodeList nList = doc.getElementsByTagName("Event");
System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("\nCurrent Element :" + nNode.getNodeName());
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
Node logTimeNode = eElement.getElementsByTagName("logTime").item(0);
String logTimeString = logTimeNode.getTextContent();
// Do some stuff with logTimeString
logTimeNode.setTextContent(logTimeString);
}
}
// write the content into xml file
String filepath = "/path/to/file.xml";
TransformerFactory transformerFactory = TransformerFactory
.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(new File(filepath));
transformer.transform(source, result);
} catch (Exception e) {
e.printStackTrace();
}
}
Related
I'm having a slight problem with XML parsing.
I'm creating a function where the parameter is a certain "element" from the XML file.
When found, I want to return the value of the root attribute.
Here's my code:
FileInputStream file = new FileInputStream(new File("C:\\Users\\Grizzly\\Java\\Projet_16_17-20161214\\bdd.xml"));
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
doc.getDocumentElement().normalize();
NodeList nList = doc.getElementsByTagName("type");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node nNode = nList.item(temp);
if(nNode.toString().equalsIgnoreCase(element))
{
Element eElement = (Element) nNode;
System.out.println("Taxe= "+ eElement.getAttribute("taxe"));
}
}
}
Any idea on how to do this?
Here's my XML file:
<?xml version="1.0"?>
-<types>
-<type id="Nourriture" taxe="0.1">
<element>pomme</element>
<element>fraise</element>
<element>fromage</element>
<element>viande rouge </element>
</type>
-<type id="Matiere Premiere" taxe="0.2">
<element>fer</element>
<element>polypropylene</element>
</type>
-<type id="Element Solide" taxe="0.3">
<element>voiture</element>
<element>planche surf</element>
<element>pistolet</element>
</type>
</types>
In my code, I tried to get the elements of a certain node from the nodelist and then compare it to the the string "element" which is the input of the user, and if they match it will check the attribute value of taxe linked to it.
Thanks in advance.
EDIT: I'm getting closer to what I need:
NodeList nList = doc.getElementsByTagName("type");
for (int temp = 0; temp < nList.getLength(); temp++)
{
Node nNode = nList.item(temp);
NodeList nChildren = nNode.getChildNodes();
Element eElement = (Element) nNode;
for(int i = 0; i < nChildren.getLength(); i++)
{
String onElement = eElement.getElementsByTagName("element").item(i).getTextContent();
if(onElement.equalsIgnoreCase(element))
{
System.out.println("id : " + eElement.getAttribute("id"));
System.out.println("taxe : " + eElement.getAttribute("taxe"));
break;
}
}
}
But it's only reading the first element... and item(i) isn't working.
Any idea?
If I understand you correctly, you are trying to fetch specific attributes (id and taxe) of all the document nodes having at least one child element with specific name (element).
Although the problem can be solved by iterating the DOM and keeping the states, I would rather delegate this task to XPath. A code with XPath will look cleaner and be more maintainable. For example, in order to fetch all elements having attributes id and taxe and a child element element you can use an XPath expression like //*[#id and #taxe element]. The matching nodes are fetched in a single line. You can simply iterate the nodes and collect the attributes as shown in the following example.
Example
public static void main(String args[]) {
String element = args.length > 0 ? args[0] : "element";
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try {
DocumentBuilder builder = factory.newDocumentBuilder();
FileInputStream file = new FileInputStream(new File("/some/file.xml"));
Document doc = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "//*[#id and #taxe and " + element + "]";
NodeList nodeList = (NodeList) xPath.compile(expression)
.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
NamedNodeMap attributes = node.getAttributes();
for (int j = 0; j < attributes.getLength(); j++) {
Node aNode = attributes.item(j);
System.out.printf(
"%s: %s\n",
aNode.getNodeName(),
aNode.getNodeValue()
);
}
}
} catch (Exception e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
Sample Output
id: Nourriture
taxe: 0.1
id: Matiere Premiere
taxe: 0.2
id: Element Solide
taxe: 0.3
Note, the sample above prints all attributes of the parent element. If you want to print only specific ones, you can, obviously, add a trivial check like this:
String aName = aNode.getNodeName();
if (aName.equals("taxe")) { // ...
But you can actually filter out the attributes with XPath:
String expression = "//*[ " + element + "]/#*[name() = 'id' or name() = 'taxe']";
NodeList nodeList = (NodeList) xPath.compile(expression)
.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodeList.getLength(); i++) {
Node node = nodeList.item(i);
System.out.printf("%s: %s\n", node.getNodeName(), node.getNodeValue());
}
The XPath expression above fetches all attribute nodes having names equal to whether id, or taxe. If you want all attributes, simply remove the last condition:
String expression = "//*[ " + element + "]/#*";
I want to iterate through XML file using JDOM and I get a NullPointerException in line 67 on my code, I try to store the XML date into a List:
public class ProduitImportXml {
public static List<Produit> getProduits() {
List<Produit> produitsList = new ArrayList<Produit>();
try {
File fXmlFile = new File("ProduitData.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize(); // optional --------
System.out.println("Root element :"
+ doc.getDocumentElement().getNodeName());
NodeList nList = doc.getElementsByTagName("produits");
System.out.println("----------------------------");
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
System.out.println("\nCurrent Element :" + nNode.getNodeName());
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element el = (Element) nNode;
int len = nNode.getChildNodes().getLength();
for (int i = 0; i<len; i++)
{
Produit p=new Produit(
el.getElementsByTagName("idProduit").item(0).getTextContent(),//return NullPointerException
el.getElementsByTagName("type").item(0).getTextContent(),
el.getElementsByTagName("marque").item(0).getTextContent(),
el.getElementsByTagName("modele").item(0).getTextContent(),
el.getElementsByTagName("libelle").item(0).getTextContent(),
el.getElementsByTagName("codeTac").item(0).getTextContent(),
el.getElementsByTagName("genCode").item(0).getTextContent());
produitsList.add(p);
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
return produitsList;
}
}
Any idea about how to solve this problem, this is the console message that I catch:
MessageBodyWriter not found for media type=application/xml, type=class java.util.ArrayList
<report id="oleg">
<title>olegitimerade rapport</title>
<id_email>joch1</id_email>
<id_email>kang15</id_email>
</report>
I am using the following code with the DOM XML parser to extract the above list an xml file.
String tag = "report";
String[] elementTags = new String[] {"title", "id_email"};
NodeList nList = this.doc.getElementsByTagName(tag);
try{
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
HashMap<String, String> attribute = new HashMap<String, String>();
Element eElement = (Element) nNode;
if(eElement.hasAttribute("id")){
String id = eElement.getAttribute("id");
attribute.put("id", id);
for (String elementTag : elementTags){
try{
int index=0;
while(null!=eElement.getElementsByTagName(elementTag).item(index).getTextContent()){
attribute.put(elementTag, eElement.getElementsByTagName(elementTag).item(index).getTextContent());
index++;
}
}catch (Exception e){
//System.out.println("id : "+id+" - Attribute element '"+ elementTag+ "' not found in XML! ["+this.xmlFile+"]");
}
}
attributes.add(attribute);
}
}
}
}catch (Exception e) {
e.printStackTrace();
}
The problem is when I get the multiple tags....I cannot extract the 2nd ID (kang15).
Clearly the while loop is incorrect, so I need a little help here fixing the issue.
while(null!=eElement.getElementsByTagName(elementTag).item(index).getTextContent()){
attribute.put(elementTag, eElement.getElementsByTagName(elementTag).item(index).getTextContent());
index++;
}
Consider using XPath for this:
XPath xpath = XPathFactory
.newInstance()
.newXPath();
Element report = (Element) xpath.evaluate("//report", doc, XPathConstants.NODE);
String id = xpath.evaluate("#id", report);
String title = xpath.evaluate("title", report);
NodeList emails = (NodeList)
xpath.evaluate("id_email/text()", report, XPathConstants.NODESET);
System.out.println(id);
System.out.println(title);
for(int i=0; i<emails.getLength(); i++) {
System.out.println(emails.item(i).getTextContent());
}
I would like to delete a child from an XML file and of course save the file after the modification.
Here is my XML file:
<?xml version="1.0" encoding="UTF-8" standalone="no"?><Customers>
<Marker>
<title>ABB EMEA</title>
</Marker>
<Marker>
<title>AllScripts</title>
</Marker>
<Marker>
<title>ARRIS (Motorola)</title>
</Marker>
<Marker>
<title>ARRIS (RWC)</title>
</Marker>
<Marker>
<title>BHS</title>
<site_location>Weinhammer, Hofhalde, Konstanz, Germany</site_location>
</Marker>
<Marker>
<title>Durst</title>
<site_location>Brixen, Italy</site_location>
</Marker>
<Marker>
<title>EMEA DEMO</title>
<site_location>AWS could</site_location>
</Marker>
<Marker>
<title>Harris</title>
</Marker>
</Customers>
I would like to complete remove the child that has the 'title' - 'Durst'.
Here is my code:
public static void Rebuild_Cords_XML (File ff)
{
try
{
DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
Document doc = docBuilder.parse(ff);
NodeList nodes = doc.getElementsByTagName("Marker");
int x=0;
for(int i=0;i<nodes.getLength();i++)
{
Node nNode = nodes.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE)
{
Element eElement = (Element) nNode;
if(eElement.getElementsByTagName("title").item(0).getTextContent().equals(("Durst")));
{
}
}
}
// write the DOM object to the file
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer=null;
try {
transformer = transformerFactory.newTransformer();
} catch (TransformerConfigurationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DOMSource domSource = new DOMSource(doc);
StreamResult streamResult = new StreamResult(ff);
try {
transformer.transform(domSource, streamResult);
} catch (TransformerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
catch (ParserConfigurationException | IOException | SAXException e) {
;}
}
As you can see I am able to detect it manually, but I do not know who to remove it, trying to access a parent node deletes other 'Marker' children but not the required one.
Please assist.
I'm not entirely sure what you're trying to delete, so here's both ways.
This will remove the entire marker which contains the title durst:
for (int i = 0; i < nodes.getLength(); i++) {
Node nNode = nodes.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if (eElement.getElementsByTagName("title").item(0).getTextContent().equals(("Durst"))) {
nNode.getParentNode().removeChild(nNode);
}
}
}
This will remove just the title tag in the marker:
for (int i = 0; i < nodes.getLength(); i++) {
Node nNode = nodes.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
if (eElement.getElementsByTagName("title").item(0).getTextContent().equals(("Durst"))) {
nNode.removeChild(eElement.getElementsByTagName("title").item(0));
}
}
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I have a XML file that I am trying to read and transform into objects. I want to transform and put all the locations in a array filled with Location objects wich are defined by a film id, a date and a amount.
Here is my XML file :
Here is my code to scan the location XML section :
public void findLocations() throws ParseException {
NodeList nList = document.getElementsByTagName("location");
Location[] locations = new Location[nList.getLength()];
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
locations[temp] = new Location(getTagValue("filmid", eElement), dateChanger(getTagValue("date", eElement)), getTagValue("amount", eElement));
System.out.println(locations[temp].getAmount()); //Outputs the good values.
}
}
System.out.println(locations[0].getAmount()); //Output : 5$
System.out.println(locations[1].getAmount()); //Output : 5$
System.out.println(locations[2].getAmount()); //Output : 5$
}
private static String getTagValue(String sTag, Element eElement) {
NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
Node nValue = (Node) nlList.item(0);
return nValue.getNodeValue();
}
The problem seems that my array is getting filled 3 times with the same location and ends up filled 3 time with the last location. The objects otherwise are well formed, so I imagine I got that part right.
You could use XPath instead...
public class TestXML03 {
public static void main(String[] args) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(false);
DocumentBuilder builder = factory.newDocumentBuilder();
Document xmlDoc = builder.parse(new File("Test.xml"));
Node root = xmlDoc.getDocumentElement();
XPathFactory xFactory = XPathFactory.newInstance();
XPath xPath = xFactory.newXPath();
XPathExpression xExpress = xPath.compile("/file/location");
NodeList nodes = (NodeList) xExpress.evaluate(root, XPathConstants.NODESET);
System.out.println("Found " + nodes.getLength() + " location nodes");
System.out.println("");
for (int index = 0; index < nodes.getLength(); index++) {
Node node = nodes.item(index);
xExpress = xPath.compile("filmid");
Node filmIDNode = (Node) xExpress.evaluate(node, XPathConstants.NODE);
System.out.println(filmIDNode.getNodeName() + " = " + filmIDNode.getTextContent());
xExpress = xPath.compile("date");
Node dateNode = (Node) xExpress.evaluate(node, XPathConstants.NODE);
System.out.println(dateNode.getNodeName() + " = " + dateNode.getTextContent());
xExpress = xPath.compile("amount");
Node amountNode = (Node) xExpress.evaluate(node, XPathConstants.NODE);
System.out.println(amountNode.getNodeName() + " = " + amountNode.getTextContent());
System.out.println("");
}
} catch (Exception exp) {
exp.printStackTrace();
}
}
}
Which outputs...
Found 3 location nodes
filmid = 100
date = 2013-01-11
amount = 4.00$
filmid = 200
date = 2013-01-13
amount = 9.00$
filmid = 334
date = 2013-01-23
amount = 5.00$
Updated After Feed-back
The Location class is maintaining a static reference to it's class fields, this means that changing the value for the field will change it for all instances of that class.
Remove the static references and it should solve the problem.
Your source is working perfectly. Simply modifying your source to output tags as below.
public static void findLocations(Document document) throws ParseException {
NodeList nList = document.getElementsByTagName("location");
Location[] locations = new Location[nList.getLength()];
for (int temp = 0; temp < nList.getLength(); temp++) {
Node nNode = nList.item(temp);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
System.out.println(getTagValue("filmid", eElement));
System.out.println(getTagValue("date", eElement));
System.out.println(getTagValue("amount", eElement));
System.out.println();
}
}
}
I got the proper output
100
2013-01-11
4.00$
200
2013-01-13
9.00$
334
2013-01-23
5.00$
Check if your XML input is proper.