XML Beans - Update and Save the XML document Object - java

I have to Update the Xml document object generated using Apache XMLbeans.There are two ways I am trying to update and save the document.
Step 1 : I am parsing the document and updating with the new values and saving with the parsed document itself.
private boolean updateContact(ContactType contacts, String contactFilePath, String name) throws Exception {
ContactsDocument contactDoc = ContactsDocument.Factory.parse(new File(contactFilePath));
ContactType contact = contactDoc.getContactType();
contact.setName(name);
contactDoc.save(new File(contactFilePath) , XmlUtils.getDefaultFileSavingOptions());
}
Step 2 : I am passing the updated document type and creating new instance of the xml document and saving with the updated type.
private boolean writeContact(ContactType contactType, String contactFilePath) throws Exception {
ContactsDocument contactsDoc = ContactsDocument.Factory.newInstance();
contactsDoc.setContactType(contactType);
contactsDoc.save(new File(contactFilePath), XmlUtils.getDefaultFileSavingOptions());
}
The step 2 is working but i want to know, will step 1 work ? and which is the efficient way of doing it for this scenario.

The Step 1 works perfect with the XML default file saving options and it does not modifies or removes any of the existing namespaces present in the file.
private boolean updateContact(ContactType contacts, String contactFilePath, String name) throws Exception {
ContactsDocument contactDoc = ContactsDocument.Factory.parse(new File(contactFilePath));
ContactType contact = contactDoc.getContactType();
contact.setName(name);
contactDoc.save(new File(contactFilePath) , XmlUtils.getDefaultFileSavingOptions());
}
It is also good approach to parse the file and save the changes on top of it, Instead of parse and instantiating the xml document for every updates.

Related

Java appendChild (CSV to XML conversion) doesn't work for ONE node

So I need to convert a CSV file to seperate XML files (one XML file per line in the CSV file). And this all works fine, except for the fact that it refuses to add one value. It adds the other without a problem, but for some mysterious reason refuses to create a tag for one of my nodes.
Document newDoc = documentBuilder.newDocument();
Element rootElement = newDoc.createElement("XMLoutput");
newDoc.appendChild(rootElement);
String header = headers.get(col);
String value = null;
String value2 = null;
if (col < rowValues.length) {
if(header.equals("delay")) {
value = rowValues[col];
Thread.sleep(Long.parseLong(value));
}
Element shipidElement = newDoc.createElement("shipID");
shipidElement.appendChild(newDoc.createTextNode(FilenameUtils.getBaseName(csvFileName)));
rootElement.appendChild(shipidElement);
if(header.equals("centraleID")) {
value = rowValues[col];
System.out.println(value); //to check if the if condition works, it does
Element centralElement = newDoc.createElement(header);
Text child = newDoc.createTextNode(value);
centralElement.appendChild(child);
rootElement.appendChild(centralElement);
}
else if(header.equals("afstandTotKade")) {
value2 = rowValues[col];
Element curElement = newDoc.createElement(header);
curElement.appendChild(newDoc.createTextNode(value2));
rootElement.appendChild(curElement);
}
String timeStamp = new SimpleDateFormat("HH:mm:ss").format(new Date());
Element timeElement = newDoc.createElement("Timestamp");
timeElement.appendChild(newDoc.createTextNode(timeStamp));
rootElement.appendChild(timeElement);
}
So in the above code, the if loop checking for CentraleID actually works, because it prints out the values, however the XML file does not add a tag, not even if I just insert a string instead of the header value. It does, however, insert the "afstandTotKade" node and timestamp node. I am dumbfounded.
PS: this is only part of the code of course, but the problem is so minute, that it seemed superfluous to add all of it.
PPS: the code was originally the same as the others, I've just been playing around.
This is the resulting XML File btw, so the other if does add the nodes, and I know the spelling is correct in checking the header because it does print out the values (the sout code) when I run it:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<XMLoutput>
<shipID>1546312</shipID>
<afstandTotKade>1000</afstandTotKade>
<Timestamp>22:06:33</Timestamp>
</XMLoutput>

CouchBase Editing documents from code

IN order to test couchbase, I am needing to create servlet that edit in 1.000 JSON documents row '"flag": false' to '"flag":true'. How i can do this?
My view, that finds documents with row '"flag": false':
function (doc, meta) {
if (meta.type == "json" && doc.flag == false) {
emit(doc.flag, null);
}
}
My servlet, that print results:
doGet(....
View view = client.getView("des1", "flag");
Query query = new Query();
query.setIncludeDocs(true);
ViewResponse result = client.query(view, query);
for(ViewRow row : result) {
resp.getWriter().println(row.getId());
}
Sorry for my bad English)
You cannot edit the fields in the JSON document directly. What you must do is to retrieve the documents you want to update (you already get them from the view), convert them to a Java object, edit the "flag" property, serialize the Java object back to JSON and replace the document with the new one.
You can use GSON to take care of the conversion between a java object and json.

Is it possible to display text on a rich text item in a DocumentContext?

I have a form that runs a java agent on the WebQueryOpen event. This agent pulls data from a DB2 database and then puts them into the computed text fields I have placed on the form and are displayed whenever I open the form in the browser. This is working for me. However, when I try to use RichTextFields I get a ClassCastException error. No document is actually saved, I just open the form in the browser using this domino URL - https://company.com/database.nsf/sampleform?OpenForm
Sample code of simple text field - Displayed with w/o problems
Document sampledoc = agentContext.getDocumentContext();
String samplestr = "sample data from db2";
sampledoc.replaceItemValue("sampletextfield", samplestr);
When I tried using rich text field
Document sampledoc = agentContext.getDocumentContext();
String samplestr = "sample data from db2";
RichTextItem rtsample = (RichTextItem)sampledoc.getFirstItem('samplerichtextfield');
rtsample.appendText(samplestr); // ClassCastException error
Basically, I wanted to use rich text field so that it could accommodate more characters in case I pull a very long string data.
Screenshot of the field (As you can see it's a RichText)
The problem is that you're trying to access a regular Item as a RichTextItem.
The RichTextItem are special fields that are created with its own method just like this:
RichTextItem rtsample = (RichTextItem)sampledoc.createRichTextItem('samplerichtextfield');
It's different to the regular Items that can be created with a simple sampledoc.replaceItemValue(etc).
So, if you want to know if a item is RichTextItem and if it does not exist, create it, you can do this:
RichTextItem rti = null;
Item item = doc.getFirstItem("somefield");
if (item != null) {
if (item instanceof RichTextItem) {
//Yay!
rti = (RichTextItem) item;
} else {
//:-(
}
} else {
rti = doc.createRichTextItem("somefield");
//etc.
}

How to Import & Export Custom Fields For Customer List in QuickBooks

In Quickbooks Pro 2009 I'm Adding and Importing list of Customers through the C# windows application. In quick book itself Import and Export options are there for customers list, but we have defined our own business validations logics and we are pushing the data to Quick book DB for customers.
In Quick Book there is a option to define custom fields under Additional Tab.
While programmatically adding Quick Book List of Customers, I'm able to add the values for Built-In Field values Like Customer Name Company Name and Etc. If I try to push the data for custom fields. Its giving me the error...
QuickBooks found an error when parsing the provided XML text stream.
If I skip the custom field data pushing operation then defined fields data passing is working fine.
My Code:
XmlDocument inputXMLDoc = new XmlDocument();
inputXMLDoc.AppendChild(inputXMLDoc.CreateXmlDeclaration("1.0", null, null));
inputXMLDoc.AppendChild(inputXMLDoc.CreateProcessingInstruction("qbxml", "version=\"2.0\""));
XmlElement qbXML = inputXMLDoc.CreateElement("QBXML");
inputXMLDoc.AppendChild(qbXML);
XmlElement qbXMLMsgsRq = inputXMLDoc.CreateElement("QBXMLMsgsRq");
qbXML.AppendChild(qbXMLMsgsRq);
qbXMLMsgsRq.SetAttribute("onError", "stopOnError");
XmlElement custAddRq = inputXMLDoc.CreateElement("CustomerAddRq");
qbXMLMsgsRq.AppendChild(custAddRq);
custAddRq.SetAttribute("requestID", "1");
XmlElement custAdd = inputXMLDoc.CreateElement("CustomerAdd");
custAddRq.AppendChild(custAdd);
//In-Built Columns
custAdd.AppendChild(inputXMLDoc.CreateElement("Name")).InnerText = Name;
custAdd.AppendChild(inputXMLDoc.CreateElement("AccountNumber")).InnerText = AccountNumber;
//Defined Custom Columns
custAdd.AppendChild(inputXMLDoc.CreateElement("CUSTFLD1")).InnerText = JRNL_NO;
String name = CustName.Text.Trim();
string input = inputXMLDoc.OuterXml;
//Push the Data to do the qbXMLRP request
RequestProcessor2 rp = null;
string ticket = null;
string response = null;
try
{
rp = new RequestProcessor2();
rp.OpenConnection("", "IDN CustomerAdd C# sample");
ticket = rp.BeginSession("", QBFileMode.qbFileOpenDoNotCare);
response = rp.ProcessRequest(ticket, input);
}
catch (System.Runtime.InteropServices.COMException ex)
{
MessageBox.Show("COM Error Description = " + ex.Message, "COM error");
}
What am I doing wrong here.. any helps?? or any suggestions / Ideas ????
QuickBooks has a very specific syntax you have to follow (defined by an XML .XSD) when creating requests for it to process. You can't just make up new XML nodes and expect them to work.
Thus, this is going to break things:
//Defined Custom Columns
custAdd.AppendChild(inputXMLDoc.CreateElement("CUSTFLD1")).InnerText = JRNL_NO;
Custom fields are added/modified by sending DataExt requests to QuickBooks. They are entirely separate from the main CustomerAdd or CustomerMod request. To add the custom fields, you can either send an entirely separate request:
<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="7.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<DataExtModRq>
<DataExtMod>
<OwnerID>0</OwnerID>
<DataExtName>Your Custom Field Name</DataExtName>
<ListDataExtType>Customer</ListDataExtType>
<ListObjRef>
<FullName>Your Customer Name</FullName>
</ListObjRef>
<DataExtValue>Custom field value</DataExtValue>
</DataExtMod>
</DataExtModRq>
</QBXMLMsgsRq>
</QBXML>
Or, you can chain the two requests together:
<?xml version="1.0" encoding="utf-8"?>
<?qbxml version="7.0"?>
<QBXML>
<QBXMLMsgsRq onError="stopOnError">
<CustomerAddRq requestID="Q3VzdG9tZXJBZGR8MTExMTIxMjE=">
<CustomerAdd>
<Name>Keith Palmer Jr.</Name>
<FirstName>Keith</FirstName>
<MiddleName></MiddleName>
<LastName>Palmer Jr.</LastName>
<BillAddress>
<Addr1>134 Stonemill Road</Addr1>
<City>Mansfield</City>
<State>CT</State>
<PostalCode>06268</PostalCode>
<Country>USA</Country>
</BillAddress>
<Phone>999-99-9999</Phone>
<Email>test#example.com</Email>
<Contact>Keith Palmer Jr.</Contact>
</CustomerAdd>
</CustomerAddRq>
<DataExtModRq>
<DataExtMod>
<OwnerID>0</OwnerID>
<DataExtName>Your Custom Field Name</DataExtName>
<ListDataExtType>Customer</ListDataExtType>
<ListObjRef>
<FullName>Keith Palmer Jr.</FullName>
</ListObjRef>
<DataExtValue>Custom field value</DataExtValue>
</DataExtMod>
</DataExtModRq>
</QBXMLMsgsRq>
</QBXML>
Additional examples can be found on our QuickBooks development wiki.

Extracting Values From an XML File Either using XPath, SAX or DOM for this Specific Scenario

I am currently working on an academic project, developing in Java and XML. Actual task is to parse XML, passing required values preferably in HashMap for further processing. Here is the short snippet of actual XML.
<root>
<BugReport ID = "1">
<Title>"(495584) Firefox - search suggestions passes wrong previous result to form history"</Title>
<Turn>
<Date>'2009-06-14 18:55:25'</Date>
<From>'Justin Dolske'</From>
<Text>
<Sentence ID = "3.1"> Created an attachment (id=383211) [details] Patch v.2</Sentence>
<Sentence ID = "3.2"> Ah. So, there's a ._formHistoryResult in the....</Sentence>
<Sentence ID = "3.3"> The simple fix it to just discard the service's form history result.</Sentence>
<Sentence ID = "3.4"> Otherwise it's trying to use a old form history result that no longer applies for the search string.</Sentence>
</Text>
</Turn>
<Turn>
<Date>'2009-06-19 12:07:34'</Date>
<From>'Gavin Sharp'</From>
<Text>
<Sentence ID = "4.1"> (From update of attachment 383211 [details])</Sentence>
<Sentence ID = "4.2"> Perhaps we should rename one of them to _fhResult just to reduce confusion?</Sentence>
</Text>
</Turn>
<Turn>
<Date>'2009-06-19 13:17:56'</Date>
<From>'Justin Dolske'</From>
<Text>
<Sentence ID = "5.1"> (In reply to comment #3)</Sentence>
<Sentence ID = "5.2"> &gt; (From update of attachment 383211 [details] [details])</Sentence>
<Sentence ID = "5.3"> &gt; Perhaps we should rename one of them to _fhResult just to reduce confusion?</Sentence>
<Sentence ID = "5.4"> Good point.</Sentence>
<Sentence ID = "5.5"> I renamed the one in the wrapper to _formHistResult. </Sentence>
<Sentence ID = "5.6"> fhResult seemed maybe a bit too short.</Sentence>
</Text>
</Turn>
.....
and so on
</BugReport>
There are many commenter like 'Justin Dolske' who have commented on this report and what I actually looking for is the list of commenter and all sentences they have written in a whole XML file. Something like if(from == justin dolske) getHisAllSentences(). Similarly for other commenters (for all). I have tried many different ways to get the sentences only for 'Justin dolske' or other commenters, even in a generic form for all using XPath, SAX and DOM but failed. I am quite new to these technologies including JAVA and any don't know how to achieve it.
Can anyone guide me specifically how could I get it with any of above technologies or is there any other better strategy to do it?
(Note: Later I want to put it in a hashmap such as like this HashMap (key, value) where key = name of commenter (justin dolske) and value is (all sentences))
Urgent help will be highly appreciated.
There're several ways using which you can achieve your requirement.
One way would be use JAXB. There're several tutorials available on this on the web, so feel free to refer to them.
You can also think of creating a DOM and then extracting data from it and then put it into your HashMap.
One reference implementation would be something like this:
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class XMLReader {
private HashMap<String,ArrayList<String>> namesSentencesMap;
public XMLReader() {
namesSentencesMap = new HashMap<String, ArrayList<String>>();
}
private Document getDocument(String fileName){
Document document = null;
try{
document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new File(fileName));
}catch(Exception exe){
//handle exception
}
return document;
}
private void buildNamesSentencesMap(Document document){
if(document == null){
return;
}
//Get each Turn block
NodeList turnList = document.getElementsByTagName("Turn");
String fromName = null;
NodeList sentenceNodeList = null;
for(int turnIndex = 0; turnIndex < turnList.getLength(); turnIndex++){
Element turnElement = (Element)turnList.item(turnIndex);
//Assumption: <From> element
Element fromElement = (Element) turnElement.getElementsByTagName("From").item(0);
fromName = fromElement.getTextContent();
//Extracting sentences - First check whether the map contains
//an ArrayList corresponding to the name. If yes, then use that,
//else create a new one
ArrayList<String> sentenceList = namesSentencesMap.get(fromName);
if(sentenceList == null){
sentenceList = new ArrayList<String>();
}
//Extract sentences from the Turn node
try{
sentenceNodeList = turnElement.getElementsByTagName("Sentence");
for(int sentenceIndex = 0; sentenceIndex < sentenceNodeList.getLength(); sentenceIndex++){
sentenceList.add(((Element)sentenceNodeList.item(sentenceIndex)).getTextContent());
}
}finally{
sentenceNodeList = null;
}
//Put the list back in the map
namesSentencesMap.put(fromName, sentenceList);
}
}
public static void main(String[] args) {
XMLReader reader = new XMLReader();
reader.buildNamesSentencesMap(reader.getDocument("<your_xml_file>"));
for(String names: reader.namesSentencesMap.keySet()){
System.out.println("Name: "+names+"\tTotal Sentences: "+reader.namesSentencesMap.get(names).size());
}
}
}
Note: This is just a demonstration and you would need to modify it to suit your need. I've created it based on your XML to show one way of doing it.
I suggest to use JAXB to creates a Data Model reflecting your XML structure.
One done, you can load the XML into Java instances.
Put each 'Turn' into a Map< String, List< Turn >>, using Turn.From as key.
Once done, you'll can write:
List< Turn > justinsTurn = allTurns.get( "'Justin Dolske'" );

Categories

Resources