Codesynthesis - Compare string value with sequence in C++ - c++

I'm new to Codesynthesis and i'm wondering about how i can compare string values with a sequence.
For example i have a Message id "0x100" and i want to check if its in the Send sequences. If its there, i just want to get the Signal name of the Message with the id "0x100" (in this case: "one") and not the whole sequence.
With my code i can get all the Message ids in all Send sequences, but i dont know how to use them to compare it to a string variable respectively just get one element out of the sequence and save it to a string variable.
How can i accomplish this?
Thanks for your help!
This is the xml:
<record>
<signals>
<Send name="Port1">
<Message id="0x100">
<Signal name="one"/>
</Message>
<Message id="0x101">
<Signal name="two"/>
<Signal name="three"/>
<Signal name="four"/>
</Message>
<Message id="0x102">
<Signal name="five"/>
</Message>
<Message id="0x103">
<Signal name="six"/>
</Message>
<Message id="0x104">
<Signal name="seven"/>
<Signal name="eight"/>
<Signal name="nine"/>
<Signal name="ten"/>
</Message>
<Message id="0x105">
<Signal name="eleven"/>
</Message>
</Send>
<Send name="Port2">
<Message id="0x106">
<Signal name="twelve"/>
</Message>
<Message id="0x107">
<Signal name="thirteen"/>
</Message>
<Message id="0x108">
<Signal name="fourteen"/>
</Message>
<Message id="0x109">
<Signal name="fifteen"/>
</Message>
<Message id="0x110">
<Signal name="sixteen"/>
</Message>
</Send>
</signals>
</record>
This is how i read the sequences from the xml:
string filename = "test.xml";
unique_ptr<record> h(record(filename));
signals::Send_sequence& s(h->signals().Send());
for (signals::Send_iterator i(s.begin()); i != s.end(); ++i)
{
Send::Message_sequence& s2(i->Message());
for (Send::Message_iterator j(s2.begin()); j != s2.end(); ++j)
{
Message& u(*j);
cout << u.id() << endl;
}
}

FYI: I found the solution. It was quite easy.
string filename = "test.xml";
unique_ptr<record> h(record(filename));
signals::Send_sequence& s(h->signals().Send());
for (signals::Send_iterator i(s.begin()); i != s.end(); ++i)
{
Send::Message_sequence& s2(i->Message());
for (Send::Message_iterator j(s2.begin()); j != s2.end(); ++j)
{
Message& u(*j);
cout << u.id() << endl;
//Check if theres a message
if (u.id().present()) {
//Put the message in a struct array (same with signals)
info[NumberOfSends].messages[NumberOfMessages] = u.id().get(); //this is how you get it as a string
NumberOfMessages++;
}
}
}NumberOfSends++;
Now you can use this array to compare it to a string.

Related

Read multiple attributes from XML in QT5

I have XML with structure like this:
<?xml version="1.0"?>
<Element id="123">
<Type>Type-of-element</Type>
<time>2020-02-20 20:20:20<time>
<part name="part1" type="Mech">Back</part>
<part name="part2" type="Mech">Back</part>
<part name="part3" type="Mech">Front</part>
<part name="part4" type="Electric">Side-left</part>
<part name="part5" type="Electric">Side-right</part>
<part name="part6" type="Electric">Front</part>
</Element>
I wrote this function to read this
QXmlStreamReader x(xml);
QString partName;
QString partType;
QString partValue;
unsigned long long int elementID;
QString type;
QString time;
if (x.readNextStartElement()){
if(x.name()=="Element"){
elementID=x.attributes().value("id").toULongLong();
qDebug()<<elementID;
}
while(x.readNextStartElement()){
if(x.name()=="part"){
partName = x.attributes().value("name").toString();
partType = x.attributes().value("type").toString();
partValue = x.readElementText();
qDebug()<<partName<<" "<<partType<<" "<<partValue;
}
else if(x.name()=="Type"){
type=x.readElementText();
qDebug()<<type;
}
else if(x.name()=="time"){.
time=x.readElementText();
qDebug()<<time;
}
else{
qDebug()<<"invalid name: "<<x.name();
}
}
}
And console print just this:
123
"Type-of-element"
"20020-02-20 20:20:20"
So multiple attributes reading did not work. How I can read this?
It was a missing / in < /time> now it works perfectly :)

Parsing XML File with Boost C++

I have to parse one xml file using boost c++, I have written one test code which is working for this xml.
a.xml
<a>
<modules>
<module>abc</module>
<module>def</module>
<module>ghi</module>
</modules>
</a>
Output is coming
abc
def
ghi
but for this a.xml file, my test code is not showing any output, 3 blank lines are coming as output.
<a>
<modules>
<module value = "abc"/>
<module value = "def"/>
<module value = "abc"/>
</modules>
</a>
here is the test code:
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/foreach.hpp>
#include <iostream>
int main()
{
using boost::property_tree::ptree;
ptree pt;
read_xml("a.xml",pt);
BOOST_FOREACH(ptree::value_type &v, pt.get_child("a.modules"))
std::cout<<v.second.data()<<std::endl;
return 0;
}
My Problem is I am having a large xml file which contains the mixture of patterns from both the files and I have to parse it.
File is b.xml and I have to get message subtag from each tag.
<MultiMessage>
<Message structID="1710" msgID="0" length="50">
<structure type="AppHeader">
</structure>
</Message>
<Message structID="27057" msgID="27266" length="315">
<structure type="Container">
<productID value="166"/>
<publishTo value="xyz"/>
<templateID value="97845"/>
<sendingTime value="1421320622367060444"/>
<message value="092374NMKLA90U345N09832LJKN0A9845JHKLASDF09U8426LJAKLJDGF09845U6KLJSDGP89U45LJSDFP9GU4569078LJK"/>
</structure>
</Message>
</MultiMessage>
<MultiMessage>
<Message structID="1710" msgID="0" length="50">
<structure type="AppHeader">
</structure>
</Message>
<Message structID="27057" msgID="27266" length="315">
<structure type="Container">
<productID value="166"/>
<publishTo value="xyz"/>
<templateID value="97845"/>
<sendingTime value="1421320622367060444"/>
<message value="092374NMKLA90U345N09832LJKN0A9845JHKLASDF09U8426LJAKLJDGF09845U6KLJSDGP89U45LJSDFP9GU4569078LJK"/>
</structure>
</Message>
</MultiMessage>
<MultiMessage>
<Message structID="1710" msgID="0" length="50">
<structure type="AppHeader">
</structure>
</Message>
<Message structID="27057" msgID="27266" length="315">
<structure type="Container">
<productID value="166"/>
<publishTo value="xyz"/>
<templateID value="97845"/>
<sendingTime value="1421320622367060444"/>
<message value="092374NMKLA90U345N09832LJKN0A9845JHKLASDF09U8426LJAKLJDGF09845U6KLJSDGP89U45LJSDFP9GU4569078LJK"/>
</structure>
</Message>
</MultiMessage>
and output should be :
092374NMKLA90U345N09832LJKN0A9845JHKLASDF09U8426LJAKLJDGF09845U6KLJSDGP89U45LJSDFP9GU4569078LJK
092374NMKLA90U345N09832LJKN0A9845JHKLASDF09U8426LJAKLJDGF09845U6KLJSDGP89U45LJSDFP9GU4569078LJK
092374NMKLA90U345N09832LJKN0A9845JHKLASDF09U8426LJAKLJDGF09845U6KLJSDGP89U45LJSDFP9GU4569078LJK
Thank You
Regards
Boost Documentation:
The attributes of an XML element are stored in the subkey . There is one child node per attribute in the attribute node. Existence of the node is not guaranteed or necessary when there are no attributes.
<module value = "abc"/>
//One way would be this:
boost::get<std::string>("module.<xmlattr>.value");
One more way (untested), which appears to be better:
BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child("a.modules"))
{
std::cout << v.second.get_child("<xmlattr>.type").data() << std::endl;
std::cout << v.second.get_child("<xmlattr>.Reference").data() << std::endl;
}
One more taken from here.
//Parse XML...
BOOST_FOREACH(boost::property_tree::ptree::value_type &v, pt.get_child("a.modules"))
{
const boost::property_tree::ptree &attributes = v.second.get_child("<xmlattr>", boost::property_tree::ptree());
BOOST_FOREACH(const boost::property_tree::ptree::value_type &v, attributes)
{
std::cout << v.first.data() << std::endl;
std::cout << v.second.data() << std::endl;
}
}

Is it possible to generate non-blocking calls with dbusxx-xml2cpp?

I would like to generate C++ headers using dbusxx-xml2cpp where some methods are non-blocking, e.g. using invoke_method_noreply instead of invoke_method. Is this possible?
For example the following XML:
<?xml version="1.0" encoding="UTF-8" ?>
<node name="/me/MyService">
<interface name="me.MyService">
<method name="MyMethod">
<arg direction="in" type="s" name="argument"/>
</method>
</interface>
</node>
Would generate (partly):
void MyMethod(const std::string& argument)
{
::DBus::CallMessage call;
::DBus::MessageIter wi = call.writer();
wi << argument;
call.member("MyMethod");
::DBus::Message ret = invoke_method (call);
}
But I would like to have something like:
void MyMethod(const std::string& argument)
{
::DBus::CallMessage call;
::DBus::MessageIter wi = call.writer();
wi << argument;
call.member("MyMethod");
bool ret = invoke_method_noreply (call);
}
Use the annotation org.freedesktop.DBus.Method.NoReply"
Example XML:
<node>
<interface name="org.test.example">
<method name="NoReplyMethod">
<arg name="data" direction="in" type="i"/>
<annotation name="org.freedesktop.DBus.Method.NoReply" value="true"/>
</method>
</interface>
</node>
Generated Code:
void NoReplyMethod(const int32_t& data)
{
::DBus::CallMessage call;
::DBus::MessageIter wi = call.writer();
wi << data;
call.member("NoReplyMethod");
assert (invoke_method_noreply (call));
}

Reading xml through Qt

I am new to Qt and XML . Please help me on solving this . I shall be greatful to you .
Here is my XML file format
< SiteSpecific>
< SitesList>LocA;LocB;LocC< /SitesList>
< LocA>
< MaterialList>Material_A;Material_B</MaterialList>
<Material Name="Material_A">
<TemperatureList>-65;70;300;400;1000</TemperatureList>
<Density Value="0.286"/>
<PoissonRatio Value="0.27"/>
<Property tempid="01" temp="-65">
<Modulus Value="32.77E+6"/>
<Alpha Value="8.15E-6"/>
<YieldStrength Value="33.90E+3"/>
</Property>
<Property tempid="02" temp="70">
<Modulus Value="29.00E+6"/>
<Alpha Value="8.55E-6"/>
<YieldStrength Value="30.00E+3"/>
= </Property>
<Property tempid="03" temp="300">
<Modulus Value="27.50E+6"/>
<Alpha Value="9.26E-6"/>
<YieldStrength Value="22.40E+3"/>
</Property>
</Material>
</LocA>
< LocB>
< MaterialList>Material_C;Material_D</MaterialList>
<Material Name="Material_C">
<TemperatureList>-65;70;300;400;1000</TemperatureList>
<Density Value="0.286"/>
<PoissonRatio Value="0.27"/>
<Property tempid="01" temp="-65">
<Modulus Value="32.77E+6"/>
<Alpha Value="8.15E-6"/>
<YieldStrength Value="33.90E+3"/>
</Property>
<Material Name="Material_D">
<TemperatureList>-65;70;300;400;1000</TemperatureList>
<Density Value="0.286"/>
<PoissonRatio Value="0.27"/>
<Property tempid="01" temp="-65">
<Modulus Value="32.77E+6"/>
<Alpha Value="8.15E-6"/>
<YieldStrength Value="33.90E+3"/>
</Property>
</Material>
</LocB>
From the above file format i have to extract Materialist(e.g Material_A , Material_B , Material_C , Material_D) , Temperaturelist(e.g. -65,70,300,400,1000) and all the properties (Modulus , alpha and yieldstrength )based on tempid for LocA and LocB .
QDomDocument and QXmlStreamReader are the two main ways to read XML documents the "Qt way." Read the documentation for examples and instructions.
Personally, I prefer QXmlStreamReader, but it does have a learning curve.
Edit: Here's a little sample code, not compiled, to give you the general idea:
//create some struct to store your data
struct material_t
{
QString name;
QList<MatProp> properties; //a list of your temp-modulus-Alpha-Yield entries
}
QList<material_t> readLocation(QXmlStreamReader& xml)
{
QStringList matnames;
QList<material_t> matlist;
while(xml.readNextStartElement())
{
if(xml.name() == "MaterialList")
matnames = xml.readElementText().split(";");
else if(matnames.contains(xml.name().toString()))
matlist.append(readMaterial(xml)); //write your own reader that returns a material_t
else
xml.skipCurrentElement(); //you must skip every unwanted element
}
return matlist;
}
void readStuff(QXmlStreamReader& xml, QList<material_t>& mats)
{
while(xml.readNextStartElement())
{
QStringList sitelist;
if(xml.name() == "SitesList") //key in on the XML node name
{
sitelist = xml.readElementText().split(";");
} else if(sitelist.contains(xml.name().toString()))
{
mats.append(readLocation(xml));
} else //you have to skip every unwanted element
xml.skipCurrentElement();
}
}
int main()
{
QList<material_t> materialist;
QFile file("your path here");
if(file.open(QIODevice::Text | QIODevice::ReadOnly)) //the QIODevice must be open
{
QXmlStreamReader xml(&file);
readStuff(xml, materiallist);
}
//do stuff with materiallist
}

Junit report does not generate report if there is assertion error

Junit report does not generate report if there is assertion error
Class to be tested
public class Math {
static public int add(int a, int b) {
return a + b;
}
static public int multiply ( int a, int b) {
if(a==0&&b==0)
return 0;;
return a * b;
}
}
Junit Test class
import junit.framework.*;
public class TestMath extends TestCase {
protected void setUp() {
// put common setup code in here
}
protected void tearDown() {
// put common cleanup code in here
}
public void testAdd() {
int num1 = 3;
int num2 = 2;
int total = 5;
int sum = 0;
sum = Math.add(num1, num2);
assertEquals(sum, total);
}
public void testMulitply() {
int num1 = 3;
int num2 = 7;
int total = 21;
int sum = 0;
sum = Math.multiply(num1, num2);
assertEquals("Problem with multiply", sum, total);
num1 = 5;
num2 = 4;
total = 20;
sum = Math.multiply(num1, num2);
assertEquals("Problem with multiply", sum, total);
}
public void testv(){
Assert.assertEquals(1, Math.multiply(0, 0));
}
}
I am using junit reporting to generate reports
The problem is if assertion fails the reports are not generate , the Ant Build fails . MY assumption is the if a assertion fails it should be listed in failures rather then error in Build result.
Ant XML
<project name="SampleJUnitTests" default="dist" basedir=".">
<description>
Sample JUnit Tests
</description>
<!-- set global properties for this build -->
<property name="project_name" value="junitSamples"/>
<property name="src" location="src"/>
<property name="build" location="bin"/>
<property name="dist" location="dist"/>
<property name="lib" location="lib"/>
<property name="res" location="res"/>
<property name="reports" location="reports"/>
<!-- the names of various distributable files -->
<property name="jar_name" value="${project_name}.jar"/>
<property name="war_name" value="${project_name}.war"/>
<!-- top level targets -->
<target name="compile" depends="init" description="compile the source code " >
<javac srcdir="${src}" destdir="${build}">
<classpath>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
</javac>
</target>
<target name="dist" depends="compile" description="generate the distributable files " >
<!-- Put everything in ${build} into the MyProject-${DSTAMP}.jar file -->
<jar jarfile="${dist}/${jar_name}" basedir="${build}"/>
</target>
<target name="clean"
description="clean up" >
<!-- Delete the ${build} and ${dist} directory trees -->
<delete dir="${build}"/>
<delete dir="${dist}"/>
<delete dir="${reports}"/>
</target>
<target name="run-tests" depends="compile" description="run your test suite" >
<junit printsummary="yes" haltonfailure="yes" showoutput="yes" >
<classpath>
<pathelement path="${build}"/>
<fileset dir="lib">
<include name="**/*.jar"/>
</fileset>
</classpath>
<batchtest fork="yes" todir="${reports}/raw/">
<formatter type="xml"/>
<fileset dir="${src}">
<include name="**/*Test*.java"/>
</fileset>
</batchtest>
</junit>
</target>
<target name ="test" depends="run-tests">
<junitreport todir="${reports}">
<fileset dir="${reports}/raw/">
<include name="TEST-*.xml"/>
</fileset>
<report format="frames" todir="${reports}/html/"/>
</junitreport>
</target>
<target name ="run" depends="" description="if this project can be run, run it" >
</target>
<!-- supporting targets -->
<target name="init" description="initialize the build environment" >
<!-- Create the time stamp -->
<tstamp/>
<!-- Create directory structures -->
<mkdir dir="${build}"/>
<mkdir dir="${lib}"/>
<mkdir dir="${dist}/lib"/>
<mkdir dir="${reports}"/>
<mkdir dir="${reports}/raw/"/>
<mkdir dir="${reports}/html/"/>
</target>
<target name="all" depends="clean, test">
</target>
</project>
MY requirement is if assertion fails it should show in failure ? What do i need to do ?
This question has been answered by Tharani in the comments... Answering it to make it from unanswered...
Change the value of haltonfailure="no" it will work as expedted ...