In a Java program, i am processing an xml using dom4j.
Now, I want to update an attribute of an element.
This is the code I am using to obtain that element--
SAXReader reader = new SAXReader();
doc = reader.read(new StringReader(xmlinput));
Element root = doc.getRootElement();
for ( Iterator i = root.elementIterator( "cloudwhile" ); i.hasNext(); ) {
Element foo = (Element) i.next();
Now, I want to update the value of an attribute of element 'foo'--
For this I am trying to use the following code--
foo.setAttributeValue("indexstart", (String) newstart );
However the above method is deprecated... how do I update the attribute now? Also, I want to take the string representation of the modified xml, immediately after updating the attribute of element 'foo'- how do I do that?
JavaDoc says to use addAttribute(...) instead. The name is somewhat misleading, as it will replace the content of an existing attribute - what is equal to updating a value.
Adds the attribute value of the given fully qualified name. If an attribute already exists for the given name it will be replaced. Attributes with null values are silently ignored. If the value of the attribute is null then this method call will remove any attributes with the given name.
As it says in the docs, use addAttribute(String attributeName, String value) instead.
Related
I want to remove entrys out of an attribute map. The problem is that the remove method can't match the key I search for:
final Attributes attributes = manifest.getMainAttributes();
symbolicName = getAttributeValue(attributes, "Bundle-SymbolicName");
attributes.remove("Bundle-SymbolicName");
When i run that code, the entry with the key "Bundle-SymbolicName" (and every other i try to remove) is still in attributes.
In the debugger i can evaluate the following expressions:
attributes.getValue("Bundle-Version") = 0.1.0.qualifier
attributes.containsKey("Bundle-Version") = false
attributes.remove("Bundle-Version") returns null (Returns the previous attribute value, or null if none.)
Is this a problem with typecasting?
RealSkeptic did answer my question: The keys of Attributes are not strings. I need to use the type Attributes.Name
In Java I parse a XML document. This XML is a Purchase Order and from this XML I create a PO document in our ERP-system.
I use domparser to parse the XML.
So eventually I have code like this:
--this is an excerpt --
//ShipTo
Element shipToElement = CXMLHandlerObj.getChildElement(elementOrderRequestHeader, "ShipTo");
//Address
Element shipToAddressElement = CXMLHandlerObj.getChildElement(shipToElement, "Address");
/*get attributes of Address*/
notesHandlerObj.docOrder.replaceItemValue("ShipToParty_addressID", shipToAddressElement.getAttribute("addressID"));
notesHandlerObj.docOrder.replaceItemValue("ShipToParty_addressIDDomain", shipToAddressElement.getAttribute("addressIDDomain"));
notesHandlerObj.docOrder.replaceItemValue("ShipToParty_isoCountryCode", shipToAddressElement.getAttribute("isoCountryCode"));
But the XML also contains at the top a OrderRequestHeader which has a type attribute in it:
<OrderRequestHeader orderDate="2017-04-04T12:00:00+00:00" orderID="4550144777" orderType="regular" orderVersion="1" type="new">
Below this element all the details of the order are found.
The "type" attribute can have values like : New or Update.
The type will be "new" if the PO XML is send for the first time and the type will be "update" if the same PO is sent but then with an update contained within it.
Note that the XML structure is the same but only the type is different.
When the type is "New", I will just parse the XML and create the PO document. But if the type is "Update" then I want to check every element and update the document and mail the changes accordingly..
Now the problem is that for the parsing of the XML I need to create a new PO or update an existing one. This I can do by the following ways:
1. creating two methods :
1. create new PO
2. update PO
In the create method I can parse the xml and add values from element to the document.
In the update method I can parse again all elements but also check which data has been changed.
2. I can put a if and else statement before every element
The methods of above are a bit redudant is there any simpler way of doing this?
All,
I have multiple XML templates that I need to fill with data, to allow my document builder class to use multiple templates and insert data correctly
I designate the node that I want my class to insert data to by adding an attribute of:
id="root"
One example of an XML
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<SiebelMessage MessageId="07f33fa0-2045-46fd-b88b-5634a3de9a0b" MessageType="Integration Object" IntObjectName="" IntObjectFormat="Siebel Hierarchical" ReturnCode="0" ErrorMessage="">
<listOfReadAudit >
<readAudit id="root">
<recordId mapping="Record ID"></recordId>
<userId mapping="User ID"></userId>
<customerId mapping="Customer ID"></customerId>
<lastUpd mapping="Last Updated"></lastUpd>
<lastUpdBy mapping="Last Updated By"></lastUpdBy>
<busComp mapping="Entity Name"></busComp>
</readAudit>
</listOfReadAudit>
</SiebelMessage>
Code
expr = xpath.compile("//SiebelMessage[#id='root']");
root = (Element) expr.evaluate(xmlDoc, XPathConstants.NODE);
Element temp = (Element) root.cloneNode(true);
Using this example:
XPath to select Element by attribute value
The expression is not working:
//SiebelMessage[#id='root']
Any ideas what I am doing wrong?
Try this:
//readAudit[#id='root']
This selects all readAudit elements with the id attribute set to root (it should be just 1 element in your case).
You could make sure it returns maximum 1 element with this:
//readAudit[#id='root'][1]
What you are doing is selecting SiebelMessage nodes with the attribute id='root'.
But the SiebelMessage doesn't have an id, it's the readAudit you are after. So either do
//readAudit[id='root']
or
//SiebelMessage//readAudit[id='root']
I am reading an XML using dom4j by using XPath techniques for selecting desired nodes. Consider that my XML looks like this:
<Employees>
<Emp id=1>
<name>jame</name>
<age>12</age>
</Emp>
.
.
.
</Employees>
Now i need to store the Information of all employees in a list of my Employee Class. Until i code the following:
List<? extends Node> lstprmntEmps = document.selectNodes("//Employees/Emp");
ArrayList<Employee> Employees = new ArrayList<Employee>();//Employee is my custom class
for (Node node : lstprmntEmps)
{
Employees.add(ParseEmployee(node));//ParseEmployee(. . .) is my custom function that pareses emp XML and return Employee object
}
Now how do i get the name and age of Currently selected Node?
is there any such method exist node.getElementValue("name");
Cast each node to Element, then ask the element for its first "name" sub-element and its first "age" sub-element and get their text.
See http://dom4j.sourceforge.net/apidocs/org/dom4j/Element.html.
The elementText(String) method of Element maybe gets a sub-element by name and retrieves its text in one operation, but it's undocumented, so it's hard to say.
Note that variables and methods should always start with a lowercase letter in Java.
Update: The problem ended up being the Flash component itself. It wasn't properly compiling the multiple values from the element. I notified the developers and they implemented a workaround. Commons FileUpload does support multiple values per the accepted answer.
I have a form, enctype="multipart/form-data", with one
<select name="XX" multiple="multiple">
and a Flash upload component which allows the user to select multiple files. When handling the POST using Apache Commons FileUpload, I detect the select field via
item.isFormField() == true
and continue to extract the details via
// Process a regular form field
if (item.isFormField()) {
String name = item.getFieldName();
String value = item.getString();
}
The problem I'm having is that item.getString(); returns only the first selected value from the select field; no matter how many items I pick, I only get the first item.
Likewise, when I use the standard servlet method for parameter extraction, ie.
final String[] values = request.getParameterValues("XX");
values is empty, which I assume is because the form is encoded multipart.
How can I retrieve these multiple selected values from my multi-select field?
This (unanswered) question has also been posed on the Sun forums by another author.
Above link is not working and if someone else is facing same issue, here's how to fetch all values -
retrieve multiple values from the select field using Commons File Upload -
List items = upload.parseRequest(request);
Iterator iter = items.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
if (item.isFormField()) {
String name = item.getFieldName();
String value = item.getString();
if (name.equals("multi-select"))
completeSet = value;
}
then completeSet will have just first value. all other values of multi select are also in item with the same name (here multi-select).
So all you have to do is fetch all values one by one and then convert it into required data-type (i.e. - as collect everything in a List and convert it into String[] :) ) Eg-
List<String> completeSet=new ArrayList<String>();
if(name.equals("multi-select"))
completeSet.add(value);
This way at the end completeSet will be having all set of values.
In fact, several items can have the same fieldName, you just have to add all the item string values for the same fieldName to a collection of String and then convert that collection to an array.
Found some information there :
http://www.nabble.com/RES:-File-Upload-td25910926.html