XML root element is null. Why? - c++

I'm having a problem when I try to parse a XML, but I can not see why.
This is the XML:
<comments>
<comment>
<id>7</id>
<value>comment 1</value>
<document></document>
</comment>
</comments>
This is the my code:
DOMDocument* xmlDoc = request.parseXMLString(commentsXML);
DOMElement* rootEl = xmlDoc->getDocumentElement();
Debugging it, I got:
commentsXML = <comments><comment><id>7</id><value>comment 1</value><document></document></comment></comments>
rootEl = NULL (Why ?????)
Why my "rootEl" is null? Do you have a suggestion?
Thanks!
EDIT
I'm using Xerces (http://xerces.apache.org/xerces-c/)

Related

Tinyxml2 append function

I have been looking for a way to append my xml file using tinyxml2 but couldn't find anything. I would appreciate any help.
Here is my code:
function savedata() {
XMLNode * pRoot = xmlDoc.NewElement("Cars");
xmlDoc.InsertFirstChild(pRoot);
XMLElement * pElement = xmlDoc.NewElement("Brand");
pElement->SetText("Audi");
pRoot->InsertEndChild(pElement);
pElement = xmlDoc.NewElement("type");
pElement->SetText("4x4");
pRoot->InsertEndChild(pElement);
pElement = xmlDoc.NewElement("Date");
pElement->SetAttribute("day", 26);
pElement->SetAttribute("month", "April");
pElement->SetAttribute("Year", 2015);
pElement->SetAttribute("dateFormat", "26/04/2015");
pRoot->InsertEndChild(pElement);
XMLError eResult = xmlDoc.SaveFile("SavedData1.xml");
XMLCheckResult(eResult);
}
Everytime I run the function, the xml is overwritten and I want to append to the existing file.
My xml file:
<Cars>
<Brand>Audi</Brand>
<Whatever>anothercrap</Whatever>
<Date day="26" month="April" Year="2015" dateFormat="26/04/2015"/>
</Cars>
My root is and I want to append to the existing file. For example,
<Cars>
<Brand>Audi</Brand>
<type>4x4</type>
<Date day="26" month="April" Year="2015" dateFormat="26/04/2015"/>
<Brand>BMWM</Brand>
<type>truck</type>
<Date day="26" month="April" Year="2015" dateFormat="26/04/2015"/>
</Cars>
XML is structured data so a textual append would be tricky and possibly error-prone, as you would have to make sure you don't add the root node twice, and that you maintain indentation etc.
What might be easier is to load the XML, parse it with TinyXML, and write it back.
You can append if you use the FILE overload for xmldoc.Save.
FILE* file = fopen("myfile.xml","a");
xmlDoc.Save(file);
fclose(file);
You just have to be careful when doing this since it will mess up the doc if you're printing multiple root nodes. If you're doing this for logging purposes I would just leave out the root node entirely and just have whatever is reading the log back know to append them or just not even care about proper xml format.

Reading an XML document using pugiXml

i have a problem with parsing an xml document using pugiXml, it seems to me that everything is correct but this code doesn't work :(
void MainWindow::open()
{
QString fileName = QFileDialog::getOpenFileName(this,"Open");
xml_document doc;
doc.load_file(fileName.toStdString().c_str());
for (pugi::xml_node node : doc.child("Person"))
{
qDebug(node.child_value("nom"));
qDebug(node.child_value("Age"));
}
}
Xml file format :
<?xml version="1.0"?>
<Persons>
<Person>
<nom>Med</nom>
<Age>12</Age>
</Person>
<Person>
<nom>Nasr</nom>
<Age>14</Age>
</Person>
<Person>
<nom>Souad</nom>
<Age>52</Age>
</Person>
</Persons>
The most probable cause is that you should use doc.child("Persons").
Document object in your case has one child Persons, that has several Person children. doc.child("Person") fails to find the node and returns a null handle.
Having said that, don't forget to check load_file return value as well.

XML Getting attibute value of a Node

I am using XML DOM API in C++ to parse an XML file. I can't find any method to get the attribute value in a node element.
For example, in the following xml
<test>
<fruit count="10">
...
...
</fruit>
<test>
I need to get the count string("10") using XML APIs. Can anybody help me with some code snippets.
Use DOM Parser API to get attribute value count.
Refer below sample code:
//code to perform some process for parsing the input file and get rootElement
DOMNodeList* fruitNodes= rootElement->getElementsByTagName(XMLString::transcode("fruit"));
DOMNode* node = fruitNodes->item(0);
DOMElement* fruitElement = dynamic_cast <xercesc::DOMElement*>(node);
const XMLCh* attrValue = fruitElement->getAttribute(XMLString::transcode("count"));
you can get value 10 from attrValue using: string(XMLString::transcode(attrValue))
Based on http://msdn.microsoft.com/en-us/library/windows/desktop/ms754523(v=vs.85).aspx
Try something like:
pXMLDomNodeList = pXMLDocElement->selectNodes("/test/fruit/#count");

MSXML node.clode method does not work as expected

Using the MSXML2 functions from the "msxml3.dll" library, I'm trying to duplicate sections in an XML document, but it does not work as I expected.
Here is the XML:
<result>
<Target>
<Point>
<pos dimension="2">60.384005 5.333862</pos>
</Point>
</Target>
</result>
What I want is to add multiple sections. So I want to take the node, duplicate it and put it under the existing <Target> node. I'm almost convinced I should use the Clone method, but it does not seem to work.
The C++ code:
typedef MSXML2::IXMLDOMNodePtr XmlNode;
XmlNode pNode = pXMLRequest->selectSingleNode("//result");
if(pNode==NULL)
{ m_szErrorText = m_szErrorText + _T(" 'result' node not found");return FALSE;}
XmlNode pTargetNode = pNode->selectSingleNode("Target");
XmlNode pNewTargetNode = pTargetNode->cloneNode(true);
pNode->appendChild(pNewTargetNode);
But when I run this code nothing happens to the XML document. And when I inspect the XML text in pNewTargetNode I see it is '<result>' only which is just the name of the node While I would expect it to contain all the nodes in <Target>...</Target>. Is there something I am missing ?
I used the wrong kind of 'true'.
If I replace
XmlNode pNewTargetNode = pTargetNode->cloneNode(true);
with
XmlNode pNewTargetNode = pTargetNode->cloneNode(VARIANT_TRUE);
it works fine. I had already thought about this and used TRUE instead of true, but that does not work either.
So when using the msxml library alsways use VARIANT_BOOL, VARIANT_FALSE and VARIANT_TRUE.
Raymond Chen explains why there are so many variations:
http://blogs.msdn.com/b/oldnewthing/archive/2004/12/22/329884.aspx

How to modify the xml on onRequestscript() in SOAP UI

Here is my code which i wrote in onRequestscript
def groovyUtils = new com.eviware.soapui.support.GroovyUtils(context)
path = "D:\\Service\\something2.xml";
log.info("path = "+ path);
if (mockRequest.method == "POST" )
{
mockRunner.returnFile( mockRequest.httpResponse, new File(path))
return new com.eviware.soapui.impl.wsdl.mock.WsdlMockResult(mockRequest)
}
But this script changes my XML entirely... I want to modify an existing XML(something.xml)..
i was actually Not able to modify the xml so i thought of changinf the xml instead.But according to my business logic its wrong... So can any one help me to modify the xml
in onRequestscript....
XML like
<Something>
<Data1>
<value>100</value>
<Data1>
<Data2>
<value>200</value>
<Data2>
</Something>
to a modified like this
<Something>
<Data1>
<value>101</value>
<Data1>
<Data2>
<value>201</value>
<Data2>
</Something>
You can use XmlSlurper to parse and update values from XML file. Then generate a string from updated XML and set it to the response of your mock service.
I use free SoapUI 3.6.1 but it seems that its output object differs from your example. Revise the code for your needs.
// get and parse XML file content
path = "D:\\Service\\something2.xml";
def doc = new XmlSlurper().parse(path)
// update values
doc.Data1.value[0] = 101
doc.Data2.value[0] = 201
// generate and return XML string as service response
import groovy.xml.StreamingMarkupBuilder
def result = new StreamingMarkupBuilder().bind{ mkp.yield doc }.toString()
mockResponse.setResponseContent(result)