DOMSource remains empty for String to XML - java

I am trying to generate XML file from String using DOMParser. The code snippet is like this:
public class SomeClassToSendString ()
{
private XMLBuilder xmlBuilder;
public SomeClassToSendString(String fileName) {
this.fileName = fileName;
xmlBuilder = new XMLBuilder(fileName)
}
public void writeHeader{
xmlBuilder.writeRootElements(); }
public void writeRecords(String record){
xmlBuilder.writeRecords(record); }
public void close{
xmlBuilder.close() }
}
public class XMLBuilder {
private String fileName;
private DocumentBuilderFactory docFactory;
private DocumentBuilder docBuilder;
private Document document;
private Element rootElement;
private Element childOfRoot;
public XMLFileHandler(String fileName) throws ParserConfigurationException {
this.fileName = fileName;
docFactory = DocumentBuilderFactory.newInstance();
docBuilder = docFactory.newDocumentBuilder();
document = docBuilder.newDocument();
}
public void writeRootElements() throws AppException{
try {
// root element
rootElement = document.createElement("root");
document.appendChild(rootElement);
// child element
childOfRoot = document.createElement("childOfRoot");
rootElement.appendChild(childOfRoot);
} catch (Exception e) {
logger.error(e);
}
}
public void writeRecords(String string) {
Element childOfFirstChild = document.createElement("childOfFirstChild");
childOfRoot.appendChild(childOfFirstChild);
Element record = document.createElement("record");
record.appendChild(document.createTextNode(string));
childOfFirstChild.appendChild(record); }
public void close() {
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
DOMSource source = new DOMSource(document);
StreamResult xmlResultFile = new StreamResult(new File(fileName));
transformer.transform(source, xmlResultFile); }
}
The Document remains null so in turn the DOMSource is empty. I am unable to figure out where am I going off track.
Thanks.

Related

Generate in and out xsd(schema) for each operation from the wsdl

Generate in and out XSD(schema) for each operation from the WSDL using java.
I have a WSDL file and want to generate the separate in and out XSD(schema) for every operation. I have used the soupUI jar for the same.
Below is my WSDL and the code to generate the XSD(schema) for every operation.
Please find the WSDL at http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl
Here is the code I have used:
public class SOAPInputGenerator {
public static void main(String[] args) throws Exception {
final String INPUT_PARAMETERS = ">?<";
WsdlProject project = new WsdlProject();
WsdlInterface[] wsdls = WsdlImporter.importWsdl(project, "http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl");
WsdlInterface wsdl = wsdls[0];
for (Operation operation : wsdl.getOperationList()) {
WsdlOperation wsdlOperation = (WsdlOperation) operation;
String operationName = wsdlOperation.getName();
System.out.println(wsdlOperation.createRequest(true));
String requestString = wsdlOperation.createRequest(true);
Document doc = getDocumentFromSoapRequestString(requestString);
Element docElement = doc.getDocumentElement();
System.out.println(docElement.getTagName());
NamedNodeMap allAttributes = docElement.getAttributes();
NodeList headerElements =
docElement.getElementsByTagName("soap:Header").item(0) != null ? docElement.getElementsByTagName("soap:Header") : docElement.getElementsByTagName("soapenv:Header");
System.out.println("SOAP header :"+headerElements.item(0).getNodeName());
docElement.removeChild(headerElements.item(0));
if (docElement != null && allAttributes != null) {
while(allAttributes.getLength() != 0)
{
Node attr = allAttributes.item(0);
System.out.println("*************Node : ******"+attr.getNodeName());
docElement.removeAttribute(attr.getNodeName());
}
}
String simpleXmlStr = returnDocumentInString(doc);
simpleXmlStr = simpleXmlStr.replaceAll("soapenv", "Operation").replaceAll("soap", "Operation").replaceAll(":", "");
System.out.println(simpleXmlStr);
if (simpleXmlStr.contains(INPUT_PARAMETERS)) {
generateXsd(operationName, simpleXmlStr);
}
}
}
public static String returnDocumentInString(Document doc) {
DOMSource domSource = new DOMSource(doc);
StringWriter writer = new StringWriter();
StreamResult result = new StreamResult(writer);
TransformerFactory tf = TransformerFactory.newInstance();
Transformer transformer;
try {
transformer = tf.newTransformer();
transformer.transform(domSource, result);
} catch (TransformerConfigurationException transformerConfigurationException) {
System.out.println(transformerConfigurationException.getLocalizedMessage());
}
catch (TransformerException transformerException) {
System.out.println(transformerException.getLocalizedMessage());
}
return writer.toString();
}
public static Document getDocumentFromSoapRequestString(String xmlString) throws ParserConfigurationException, SAXException, IOException {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new InputSource(new StringReader(xmlString)));
return doc;
}
private static void generateXsd(String operationName, String soapRequestXml) throws IOException, ParseException, ParserConfigurationException, SAXException, TransformerException {
FileWriter fw = new FileWriter("exmp.xml");
fw.write(soapRequestXml);
fw.close();
XsdGen gen = new XsdGen();
File tempFile = new File("exmp.xml");
gen.parse(tempFile);
File out = new File(operationName+".xsd");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
gen.write(new FileOutputStream(out));
Document doc = builder.parse(operationName+".xsd");
Element docElement = doc.getDocumentElement();
docElement.setAttribute("targetNamespace", "Default target name space for data mapper");
DOMSource source = new DOMSource(doc);
FileWriter writer = new FileWriter(new File(operationName+".xsd"));
StreamResult result = new StreamResult(writer);
TransformerFactory transformerFactory = TransformerFactory.newInstance();
Transformer transformer = transformerFactory.newTransformer();
transformer.transform(source, result);
tempFile.delete();
}
}
I would like to know if is it good and safe approach to use the soupUI jar for the same?
Is there any alternative way to achieve the same?

XPath witn namespace - query gives not results

Without using a namespace the XPath example worked fine. A list is printed. With the namespace added, no result is returned.
How can I use namespaces and XPath properly?
My sample (minimalized) xml file is:
<?xml version="1.0" encoding="UTF-8"?>
<nodespace:Employees xmlns:nodespace="my_unique_namespace_name">
<nodespace:Employee id="1">
<nodespace:age>29</nodespace:age>
<nodespace:name>Pankaj</nodespace:name>
<nodespace:gender>Male</nodespace:gender>
<nodespace:role>Java Developer</nodespace:role>
</nodespace:Employee>
<nodespace:Employee id="2">
<nodespace:age>35</nodespace:age>
<nodespace:name>Lisa</nodespace:name>
<nodespace:gender>Female</nodespace:gender>
<nodespace:role>CEO</nodespace:role>
</nodespace:Employee>
</nodespace:Employees>
The XPath Java source code is:
public class XpathNamespaceTest {
public static final String PREFIX_NAME = "bdn";
public static final String NODESPACE_UNIQUE_NAME = "nodespace";
public static void main(String[] args) {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder;
Document doc = null;
try {
ClassLoader classLoader = new XpathNamespaceTest().getClass().getClassLoader();
URL resource = classLoader.getResource("employees_namespace.xml");
File file = new File( resource.getFile());
builder = factory.newDocumentBuilder();
doc = builder.parse(file);
XPathFactory xpathFactory = XPathFactory.newInstance();
XPath xpath = xpathFactory.newXPath();
xpath.setNamespaceContext(new NamespaceContext() {
#Override
public Iterator getPrefixes(String arg0) { return null; }
#Override
public String getPrefix(String ns) {
if(ns.equals(NODESPACE_UNIQUE_NAME)) {
return PREFIX_NAME;
}
return null;
}
#Override
public String getNamespaceURI(String arg0) {
if (PREFIX_NAME.equals(arg0)) {
return NODESPACE_UNIQUE_NAME;
}
return null;
}
});
List<String> names = getEmployeeNameWithAge(doc, xpath, 30);
System.out.println("Employees with 'age>30' are:" + Arrays.toString(names.toArray()));
} catch (ParserConfigurationException | SAXException | IOException e) {
e.printStackTrace();
}
}
private static List<String> getEmployeeNameWithAge(Document doc, XPath xpath, int age) {
List<String> list = new ArrayList<>();
try {
XPathExpression expr = xpath.compile("/bdn:Employees/bdn:Employee[bdn:age>" + age + "]/bdn:name/text()");
NodeList nodes = (NodeList) expr.evaluate(doc, XPathConstants.NODESET);
for (int i = 0; i < nodes.getLength(); i++) list.add(nodes.item(i).getNodeValue());
} catch (XPathExpressionException e) {
e.printStackTrace();
}
return list;
}
}
The namespace URI is my_unique_namespace_name so you need
public static final String NODESPACE_UNIQUE_NAME = "my_unique_namespace_name";

Android xml get node value null

i have a xml
<DatosClientes>
<User>Prueba</User>
<intUserNumber>1487</intUserNumber>
<IdUser>1328</IdUser>
</DatosClientes>
How to read data in android ? when run all time return null in node value
public static void Parse(String response){
try{
DocumentBuilderFactory dbf = DocumentBuilderFactory
.newInstance();
DocumentBuilder db = dbf.newDocumentBuilder();
InputSource is = new InputSource();
is.setCharacterStream(new StringReader(response));
Document doc = db.parse(is);
doc.getDocumentElement().normalize();
NodeList datos = doc.getElementsByTagName("DatosClientes");
XmlParse parser = new XmlParse();
for (int i = 0; i < datos.getLength(); i++) {
Node node = datos.item(i);
Element fstElmnt = (Element) node;
NodeList nameList = fstElmnt.getElementsByTagName("User");
Log.e("log",String.valueOf(nameList.item(0).getNodeValue()));
}
}catch (Exception e){
e.printStackTrace();
}
}
my objetive is finally read value and convert into ArrayList
It sounds like you are trying to get a list of the values in the XML? That is, you want:
{ "Prueba", "1487", "1328" }
For that, you can do something like:
public static final String XML_CONTENT =
"<DatosClientes>"
+ "<User>Prueba</User>"
+ "<intUserNumber>1487</intUserNumber>"
+ "<IdUser>1328</IdUser>"
+ "</DatosClientes>";
public static final Element getRootNode(final String xml) {
try {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document document = builder.parse(new InputSource(new StringReader(xml)));
return document.getDocumentElement();
} catch (ParserConfigurationException | SAXException | IOException exception) {
System.err.println(exception.getMessage());
return null;
}
}
public static final List<String> getValuesFromXml(final String xmlContent) {
Element root = getRootNode(xmlContent);
NodeList nodes = root.getElementsByTagName("*");
List<String> values = new ArrayList<>();
for (int index = 0; index < nodes.getLength(); index++) {
final String nodeValue = nodes.item(index).getTextContent();
values.add(nodeValue);
System.out.println(nodeValue);
}
return values;
}
public static void main (String[] args) {
final List<String> nodeValues = getValuesFromXml(XML_CONTENT);
}

Junit4 test implementation with parameters passed from XML, (attribute value + nodevalue)?

I know I can hardcode it (parse xml, extract), but is there a way to feed (attribute value + nodevalue) like it is done with Feed4TestNG (it currently support only csv, and excel files)?
I am new to Java, and any expert insight would be helpful. Thanks!
The body of a #Parameters is not limited to data only, you are able to use any java code you like in this method, including throwing exceptions:
#Parameters
public static Collection<Object[]> data() throws IOException {
List<Object[]> data = new ArrayList<>();
// replace getClass() with <nameofclass>.class
try(InputStream in = this.getClass().getResourceAsStream()) {
//parse body here
data.add(new Object[]{attribute, value});
}
return data;
}
Depending on what XML framework you use, you need to parse your XML nodes, and put it in the list, that you are going to return.
So this is what I end up doing here:
Please submit your correction if you think I can improve my code.
.
#RunWith(Parameterized.class)
public class DataDrivenTests {
private String c;
private String b;
private static Collection<Object[]> a;
#Parameters
public static Collection<Object[]> xmlData() throws IOException{
File file = new File("xmlfile.xml");
InputStream xml1 = new FileInputStream(file);
return new xmlData(xml1).getData();
}
public DataDrivenTests(String c, String b) {
super();
this.c = c;
this.b = b;
}
#Test
public void shouldCalculateATimesB() {
boolean assertion = false;
if(c.equals(Parser.parse("Parse this string to Attribute and Value"))){
assertion = true;
}
assertTrue(assertion);
}
}
xmlData.java
public class xmlData{
private transient Collection<Object[]> data = null;
public xmlData(final InputStream xml)throws IOException{
this.data = loadFromXml(xml);
}
public Collection<Object[]> getData(){
return data;
}
private Collection<Object[]> loadFromXml(final InputStream xml)
throws IOException {
List <Object[]> ism_code_map = new ArrayList<Object[]>();
try{
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
dbFactory.setNamespaceAware(true);
DocumentBuilder dBuilder;
dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(xml);
doc.getDocumentElement().normalize();
XPath xPath = XPathFactory.newInstance().newXPath();
XPathExpression expression = xPath.compile("//e");
NodeList nodes = (NodeList) expression.evaluate(doc, XPathConstants.NODESET);
for (int i =0; i< nodes.getLength(); i++){
Node nNode = nodes.item(i);
//System.out.println("\nCurrent Element:" + nNode.getTextContent());
if (nNode.getNodeType() == Node.ELEMENT_NODE){
Element eElement = (Element) nNode;
if(eElement.getAttribute("attrname") != null && !eElement.getAttribute("attrname").isEmpty()){
code_map.add(new Object[]{"attrname",eElement.getAttribute("attrname")});
}
}catch(ParserConfigurationException e){
e.printStackTrace();
}catch(SAXException e){
e.printStackTrace();
}catch(IOException e){
e.printStackTrace();
}catch(XPathExpressionException e){
e.printStackTrace();
}
catch(NullPointerException e){
e.printStackTrace();
}
return code_map;
}
}

XML validation in Java - why does this fail?

first time dealing with xml, so please be patient. the code below is probably evil in a million ways (I'd be very happy to hear about all of them), but the main problem is of course that it doesn't work :-)
public class Test {
private static final String JSDL_SCHEMA_URL = "http://schemas.ggf.org/jsdl/2005/11/jsdl";
private static final String JSDL_POSIX_APPLICATION_SCHEMA_URL = "http://schemas.ggf.org/jsdl/2005/11/jsdl-posix";
public static void main(String[] args) {
System.out.println(Test.createJSDLDescription("/bin/echo", "hello world"));
}
private static String createJSDLDescription(String execName, String args) {
Document jsdlJobDefinitionDocument = getJSDLJobDefinitionDocument();
String xmlString = null;
// create the elements
Element jobDescription = jsdlJobDefinitionDocument.createElement("JobDescription");
Element application = jsdlJobDefinitionDocument.createElement("Application");
Element posixApplication = jsdlJobDefinitionDocument.createElementNS(JSDL_POSIX_APPLICATION_SCHEMA_URL, "POSIXApplication");
Element executable = jsdlJobDefinitionDocument.createElement("Executable");
executable.setTextContent(execName);
Element argument = jsdlJobDefinitionDocument.createElement("Argument");
argument.setTextContent(args);
//join them into a tree
posixApplication.appendChild(executable);
posixApplication.appendChild(argument);
application.appendChild(posixApplication);
jobDescription.appendChild(application);
jsdlJobDefinitionDocument.getDocumentElement().appendChild(jobDescription);
DOMSource source = new DOMSource(jsdlJobDefinitionDocument);
validateXML(source);
try {
Transformer transformer = TransformerFactory.newInstance().newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
StreamResult result = new StreamResult(new StringWriter());
transformer.transform(source, result);
xmlString = result.getWriter().toString();
} catch (Exception e) {
e.printStackTrace();
}
return xmlString;
}
private static Document getJSDLJobDefinitionDocument() {
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
} catch (Exception e) {
e.printStackTrace();
}
DOMImplementation domImpl = builder.getDOMImplementation();
Document theDocument = domImpl.createDocument(JSDL_SCHEMA_URL, "JobDefinition", null);
return theDocument;
}
private static void validateXML(DOMSource source) {
try {
URL schemaFile = new URL(JSDL_SCHEMA_URL);
Sche maFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
Schema schema = schemaFactory.newSchema(schemaFile);
Validator validator = schema.newValidator();
DOMResult result = new DOMResult();
validator.validate(source, result);
System.out.println("is valid");
} catch (Exception e) {
e.printStackTrace();
}
}
}
it spits out a somewhat odd message:
org.xml.sax.SAXParseException: cvc-complex-type.2.4.a: Invalid content was found starting with element 'JobDescription'. One of '{"http://schemas.ggf.org/jsdl/2005/11/jsdl":JobDescription}' is expected.
Where am I going wrong here?
Thanks a lot
I think you are missing the namespace on your elements. Rather than calling createElement(), you can try
document.createElementNS(JSDL_SCHEMA_URL, elementName)
If necessary, you may need to use a prefix, e.g.
document.createElementNS(JSDL_SCHEMA_URL, "jsdl:"+elementName)

Categories