<Request>
<EMPId>?</EMPId>
</Request>
I know this is a repeated question, but i would like to post it again as i dint get a convincing answer from any of the threads i went through.
My ultimate aim is to add the XML given above as the Body content of a SOAP message.
You can have a look at the following link to see how i am doing it.
Namespace related error on creating SOAP Request
It worked fine when i was using the Websphere Application Server 7.0 library.JRE is also present, forgot to include in screen shot.
Since i have to export it as a jar and run it as a stand alone application, i have to remove the dependency of 'Websphere Application Server 7.0 library'. Because, by keeping this library, my jar size will go above 100MB. So i thought of taking only the library which i needed.
'com.ibm.ws.prereq.soap.jar'
Now the issue is, the Request tag of the generated SOAP request is coming in following format.
<Request xmlns="">
<EMPId>?</EMPId>
</Request>
I am able to create a 'org.w3c.dom.Document' representation for the generated SOAP message.
Now, can any one tell me how can I delete the xmlns="" from Request tag.
The simplest way what i found is:
first:
in child set nasmespace as in root:
second:
remove namespace
Document doc = new Document();
Namespace xmlns = Namespace.getNamespace("http://www.microsoft.com/networking/WLAN/profile/v1");
Element rootXML = new Element("WLANProfile", xmlns);
Element nameXML = new Element("name");
nameXML.addContent(name);
rootXML.addContent(nameXML);
//below solution
nameXML.setNamespace(xmlns);
nameXML.removeNamespaceDeclaration(xmlns);
Finally I found several solutions of the described problem.
First, you can remove all namespaces from all xml using this answer.
Second, if you do not need to remove all namespaces in Xml, but only empty ones, they arise due to the fact that some namespace is written in the root elements, which is not in the child. For example:
<ЭДПФР xmlns="http://пф.рф/КСАФ/2018-04-03"
xmlns:АФ4="xx"...>
<КСАФ xmlns="">
...
</КСАФ>
So you need to set the same namespace for all children of root elements. It can be done using this code (call setTheSameNamespaceForChildren(rootElement) for root element before saving):
private static final String namespaceKey = "xmlns";
private static String namespaceValue;
public static void setTheSameNamespaceForChildren(Element rootEl) {
namespaceValue = rootEl.getAttribute(namespaceKey);
NodeList list = rootEl.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node child = list.item(i);
setTheSameNamespaceRecursively(child);
}
}
private static void setTheSameNamespaceRecursively(Node node) {
if (node.getNodeType() == Node.ELEMENT_NODE) {
boolean isChanged = setTheSameNamespace((Element) node);
if (isChanged) {
NodeList list = node.getChildNodes();
for (int i = 0; i < list.getLength(); i++) {
Node child = list.item(i);
setTheSameNamespaceRecursively(child);
}
}
}
}
private static boolean setTheSameNamespace(Element node) {
String curValue = node.getAttribute(namespaceKey);
if (curValue.length() == 0) {
node.setAttribute(namespaceKey, namespaceValue);
return true;
}
return false;
}
Related
Xml documents may show namespace prefix declarations in their root element. As I am new to StaxMate I managed to process xml input events for elements and element attributes. However, I never got a Namespace event.
<?xml version="1.0" encoding="UTF-8"?>
<myRoot xmlns="http://myurl.com/myProject"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mya="http://myurl.com/myAttributes"
xsi:schemaLocation="http://myurl.com/myProject ./../../main/xsd/mySchema.xsd ">
<myElement mya:myAttribute="attribute content">
<mySubElement>subelements content</original>
</myElement>
</myRoot>
When processing the element myRoot how to get the xmlns namespaces? E.g. in order to output some of them to the root element of the SMOutputDocument?
Found out by experimenting. Following is a - somewhat useless - operation to copy an XML document, including all namespace declarations. Its purpose here is to exemplify how to cope with namespaces in StaxMate.
It is called once with a SMOutputDocument as SMOutputContainer. The cursor points to root element for the output.
After that it recursively explores and copies all elements found.
private void processStartElement(SMInputCursor cursor, SMOutputContainer element) throws XMLStreamException {
SMOutputElement loe = element.addElement(cursor.getPrefixedName());
// add all namespace declarationss to the element
for (int i = 0; i < cursor.getStreamReader().getNamespaceCount(); i++) {
loe.predeclareNamespace(element.getNamespace(
cursor.getStreamReader().getNamespaceURI(i),
cursor.getStreamReader().getNamespacePrefix(i)));
}
for (int i = 0; i < cursor.getAttrCount(); i++) {
loe.addAttribute(
element.getNamespace(cursor.getAttrNsUri(i)),
cursor.getAttrLocalName(i),
cursor.getAttrValue(i));
}
SMInputCursor lc = cursor.childCursor();
while ((lc != null) && (lc.getNext() != null)) {
this.processStartElement(lc, loe);
}
}
This code returs only one "question " tag's element but I have another 9 question element inside the xml file.What is the wrong thing in here?Do I need to loop.Because when I checked the loop, it loops only one time.What is the problem?I am figure out.
Here is my xml:
<Results>
<question>
<eno>3</eno>
<qno>1</qno>
<qtext>The Battle of Gettysburg was fought during which war?</qtext>
<correctAnswer>C</correctAnswer>
</question>
<question>
<eno>3</eno>
<qno>2</qno>
<qtext>Neil Armstrong and Buzz Aldrin walked how many
minutes on the moon in 1696?</qtext>
<correctAnswer>B</correctAnswer>
</question>
</Results>
my source code:
NodeList listOfQuestions = doc.getElementsByTagName("question");
for(int s=0; s<listOfQuestions.getLength(); s++)
{
System.out.println(listOfQuestions.getLength());
Node firstQuestionNode = listOfQuestions.item(0);
if(firstQuestionNode.getNodeType() == Node.ELEMENT_NODE){
Element firstQElement = (Element)firstQuestionNode;
NodeList enoList = firstQElement.getElementsByTagName("eno");
Element enoElement =(Element)enoList.item(s);
NodeList enosList = enoElement.getChildNodes();
String eno=((Node)enosList.item(s)).getNodeValue().trim();
System.out.println(eno);
NodeList qnoList = firstQElement.getElementsByTagName("qno");
Element qnoElement =(Element)qnoList.item(s);
NodeList qnosList = qnoElement.getChildNodes();
String qno= ((Node)qnosList.item(s)).getNodeValue().trim();
System.out.println(qno);
NodeList qtextList = firstQElement.getElementsByTagName("qtext");
Element qtextElement =(Element)qtextList.item(s);
NodeList qtextsList = qtextElement.getChildNodes();
String qtext= ((Node)qtextsList.item(s)).getNodeValue().trim();
System.out.println(qtext);
NodeList correctAnswerList = firstQElement.getElementsByTagName("correctAnswer");
Element correctAnswerElement =(Element)correctAnswerList.item(s);
NodeList correctAnswerElementList = correctAnswerElement.getChildNodes();
String correctAnswer= ((Node)correctAnswerElementList.item(s)).getNodeValue().trim();
System.out.println(correctAnswer);
int i=st.executeUpdate("insert into question(eno,qno,qtext,correctAnswer) values('"+eno+"','"+qno+"','"+qtext+"','"+correctAnswer+"')");
System.out.println("s is"+s);
}
}
You have hardcoded
Node firstQuestionNode = listOfQuestions.item(0);
^^^
I think you meant to use the variable s there... or maybe not, it's hard to tell what you're trying to do. Regardless, there are no other references to listOfQuestions and you never retrieve any node except the first one.
You should have a look at jsoup, it is an API specifically built for parsing HTML DOM code in java and has tons of extra features. Also, what you are currently trying to extract would not be more than just 3-4 LOC using the API components.
Look at their example on their website for connection to an URL and fetching DOM-Elements is just 2 LOC:
Document doc = Jsoup.connect("http://en.wikipedia.org/").get();
Elements newsHeadlines = doc.select("#mp-itn b a");
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>
I have an XML file containing a bunch of simulation settings (partial example below). I would like to load these settings into a Java class, so that the settings are available later without having to write cumbersome DOM/XPath jargon (and import the associated packages) every time I (or another programmer who isn't fluent in DOM/XPath) want to access a specific setting.
Right now I set up a number of sub-classes that represent each level of information in the XML tree, and "manually" parse out the info to all these sub-classes. The result is, for example, that if I want to get Direction number 3, I can write:
settings.setup.directions[3]
I guess this works ok, but it sure feels rigid.
Is there a smarter way of doing this? Should we just stick to the DOM and skip this conversion business? (Please no!)
Note that I am not looking for instructions on how to load an XML file -- I know how to load it into a DOM document and parse it with XPath.
<?xml version="1.0"?>
<Settings>
<Identity>
<JobNumber>1234567</JobNumber>
<SimulationName>MyTest</SimulationName>
</Identity>
<PreProcessing >
<Tolerance>0.01</Tolerance>
</PreProcessing >
<PreprocessedInputData>
<PreChewedThing></PreChewedThing>
<OtherThing></OtherThing>
</PreprocessedInputData>
<Setup>
<DomainExtent>
<XMin>260</XMin>
<XMax>290</XMax>
<YMin>523</YMin>
<YMax>565</YMax>
</DomainExtent>
<Directions>
<Direction Index = "1">0</Direction>
<Direction Index = "2">10</Direction>
<Direction Index = "3">20</Direction>
<Direction Index = "4">30</Direction>
</Directions>
</Setup>
</Settings>
You can use JAXB for this purpose, it is meant to bind XML to Java classes.
There is a useful guide on http://jaxb.java.net/guide/ and a tutorial on http://jaxb.java.net/tutorial/
If you have flexibility over the layout of the XML file, and don't especially need to use a settings class with JAXB, try Commons Configuration:
Creating an XML settings file is as easy as:
XMLConfiguration configCreate = new XMLConfiguration();
configCreate.setFileName("settings.xml");
configCreate.addProperty("somesetting", "somevalue");
configCreate.save();
Reading from the XML settings file:
XMLConfiguration configRead = new XMLConfiguration("settings.xml");
String settingValue = configRead.getString("somesetting");
See http://commons.apache.org/configuration/
In my opinion, the best and simpliest way is using Java and XPath. This is an example:
<settings>
<type>jdbc-mysql</tipus>
<usr>usr</usr>
<pass>pass</pass>
<url>jdbc:mysql://192.168.1.123:3306/notifications_db</url>
<schema>notificacions_db</schema>
<date_format>yyyy-MM-dd HH:mm:ss</date_format>
<prefix_package>false</prefix_package>
<use_ssl>false</use_ssl>
<auto_reconnect>true</auto_reconnect></settings>
Java main class Example:
public static void main(String[] args) {
XPath xpath = XPathFactory.newInstance().newXPath();
String xpathExpression = "/settings";
InputSource inputSource = new InputSource("basedao-settings.xml");
try {
NodeList lstRoot = (NodeList) xpath.compile(xpathExpression).evaluate(inputSource, XPathConstants.NODESET);
NodeList lstChilds = lstRoot.item(0).getChildNodes();
for (int i = 0; i < lstChilds.getLength(); i++) {
System.out.println(lstChilds.item(i).getLocalName());
System.out.println(lstChilds.item(i).getTextContent());
}
} catch (XPathExpressionException e) {
e.printStackTrace();
}
}
My goal is to take an XML string and parse it with XMLBeans XmlObject and add a few child nodes.
Here's an example document (xmlString),
<?xml version="1.0"?>
<rootNode>
<person>
<emailAddress>joefoo#example.com</emailAddress>
</person>
</rootNode>
Here's the way I'd like the XML document to be after adding some nodes,
<?xml version="1.0"?>
<rootNode>
<person>
<emailAddress>joefoo#example.com</emailAddress>
<phoneNumbers>
<home>555-555-5555</home>
<work>555-555-5555</work>
<phoneNumbers>
</person>
</rootNode>
Basically, just adding the <phoneNumbers/> node with two child nodes <home/> and <work/>.
This is as far as I've gotten,
XmlObject xml = XmlObject.Factory.parse(xmlString);
Thank you
Here is an example of using the XmlCursor to insert new elements. You can also get a DOM Node for an XmlObject and using those APIs.
import org.apache.xmlbeans.*;
/**
* Adding nodes to xml using XmlCursor.
* #see http://xmlbeans.apache.org/docs/2.4.0/guide/conNavigatingXMLwithCursors.html
* #see http://xmlbeans.apache.org/docs/2.4.0/reference/org/apache/xmlbeans/XmlCursor.html
*/
public class AddNodes
{
public static final String xml =
"<rootNode>\n" +
" <person>\n" +
" <emailAddress>joefoo#example.com</emailAddress>\n" +
" </person>\n" +
"</rootNode>\n";
public static XmlOptions saveOptions = new XmlOptions().setSavePrettyPrint().setSavePrettyPrintIndent(2);
public static void main(String[] args) throws XmlException
{
XmlObject xobj = XmlObject.Factory.parse(xml);
XmlCursor cur = null;
try
{
cur = xobj.newCursor();
// We could use the convenient xobj.selectPath() or cur.selectPath()
// to position the cursor on the <person> element, but let's use the
// cursor's toChild() instead.
cur.toChild("rootNode");
cur.toChild("person");
// Move to </person> end element.
cur.toEndToken();
// Start a new <phoneNumbers> element
cur.beginElement("phoneNumbers");
// Start a new <work> element
cur.beginElement("work");
cur.insertChars("555-555-5555");
// Move past the </work> end element
cur.toNextToken();
// Or insert a new element the easy way in one step...
cur.insertElementWithText("home", "555-555-5555");
}
finally
{
if (cur != null) cur.dispose();
}
System.out.println(xobj.xmlText(saveOptions));
}
}
XMLBeans seems like a hassle, here's a solution using XOM:
import nu.xom.*;
Builder = new Builder();
Document doc = builder.build(new java.io.StringBufferInputStream(inputXml));
Nodes nodes = doc.query("person");
Element homePhone = new Element("home");
homePhone.addChild(new Text("555-555-5555"));
Element workPhone = new Element("work");
workPhone.addChild(new Text("555-555-5555"));
Element phoneNumbers = new Element("phoneNumbers");
phoneNumbers.addChild(homePhone);
phoneNumbers.addChild(workPhone);
nodes[0].addChild(phoneNumbers);
System.out.println(doc.toXML()); // should print modified xml
It may be a little difficult to manipulate the objects using just the XmlObject interface. Have you considered generating the XMLBEANS java objects from this xml?
If you don't have XSD for this schema you can generate it using XMLSPY or some such tools.
If you just want XML manipulation (i.e, adding nodes) you could try some other APIs like jdom or xstream or some such thing.
Method getDomNode() gives you access to the underlying W3C DOM Node. Then you can append childs using W3C Document interface.