Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Message Queue 2

Status
Not open for further replies.

unclecake2

Programmer
Jul 20, 2009
20
0
0
US
Hi, I have been given the task of adding and receiving message queue messages (MSMQ) using VB.NET. I have been working on this for a few days, and I just don't get it. I have been given 4 different XSD files, I will post two of them below.

Code:
<?xml version="1.0" encoding="utf-8" ?>
<xs:schema id="Retest" targetNamespace="[URL unfurl="true"]http://tempuri.org/Retest.xsd"[/URL] elementFormDefault="qualified"
	xmlns="[URL unfurl="true"]http://tempuri.org/Retest.xsd"[/URL] xmlns:mstns="[URL unfurl="true"]http://tempuri.org/Retest.xsd"[/URL] xmlns:xs="[URL unfurl="true"]http://www.w3.org/2001/XMLSchema">[/URL]
	<xs:element name="retest">
		<xs:complexType>
			<xs:sequence />
		</xs:complexType>
	</xs:element>
</xs:schema>

I am told it should produce a result like this:
Code:
<retest />

As well, I have another XSD like this:
Code:
<?xml version="1.0" encoding="UTF-16" ?>
<xs:schema xmlns:xs="[URL unfurl="true"]http://www.w3.org/2001/XMLSchema"[/URL] elementFormDefault="qualified" attributeFormDefault="unqualified">
	<xs:element name="request">
		<xs:annotation>
			<xs:documentation>Comment describing your root element</xs:documentation>
		</xs:annotation>
		<xs:complexType>
			<xs:sequence minOccurs="1">
				<xs:element name="job" type="xs:string" minOccurs="1" />
			</xs:sequence>
			<xs:attribute name="bsn" use="required" type="xs:string"></xs:attribute>
			<xs:attribute name="barcode" type="xs:string" use="required" />
			<xs:attribute name="jobtype" type="xs:string" use="required" />
			<xs:attribute name="jobtype" type="xs:string" use="required" />
			<xs:attribute name="message" type="xs:string" use="required" />
			<xs:attribute name="testmask" type="xs:string" use="required" />
		</xs:complexType>
	</xs:element>
</xs:schema>

Which should produce a result like this:
Code:
<result>
<job bsn="1234567" barcode="D1234567X01" jobtype="driver" overallresult="pass"></job>
<tester name="tester1" lane="1" version="1.10"></tester>
<tests performed="2006-04-13 13:45:06" cycletime="76.3" faultcode="0001" faultmessage="helpful message">
<test name="continuity" result="pass" value="1" status="1" expectedvalue=”1”  lowerlimit="" upperlimit="" units="" ></test>
<test name="straingage" result="pass" value="5.67" expectedvalue=”5.53” status="1" lowerlimit="4.23" upperlimit="6.21" units="volts"></test>
</tests>
</result>

I am able to write and read a XML formatted message, but not with multiple elements. This is my first experience with XML. I don't totally understand simple and complex type.

If anyone could direct me to where I could find code examples or offer any help it would be appreciated. I am desperate.

-UC
 
What are you trying to do with the files? An XSD file is just an XML schema, something to test an XML file against to make sure it's formatted correctly, they don't contain any actual data. It looks like the you have 2 schemas, each with an example of the XML you'll be sending or receiving, depending on what your program is doing. The XSD files aren't generating anything on their own.

A simple type has just one value. Complex type have attributes or values that are elements with values and/or attributes of their own. Here's a pretty decent article describing simple vs complex data types. It isn't .Net specific, but might help you make some sense out of the files you have.
 
I am not sure how much of the big picture will help, but this is what I am trying to do with the files. I have a customer that is putting a file in the message queue that tells me to test accuracy of brackets on a seat. When the file is in the queue, I receive it in VB.Net, which communicates with some vision software to look at the seat and give me some results on the test.

I have to write the results back to a different message queue where their system will read the file and know what to do with the seat. As well, I have buttons which will be pushed which will also write something simple to the message queue like
Code:
<retest />

I have all of the vision communication part complete, I just need to learn how to write and read the XML files to the message queue.

So, after I run my vision test in VB.Net I will have many variables available and I have to make it into a XML message queue file. How would I write a file like this having all of the variables, I just have to plug them in?

I have worked on it and I can write an xml file, but I don't know how to make it in this format. I can post what I can do if that would help.

Code:
<result>
<job bsn="1234567" barcode="D1234567X01" jobtype="driver" overallresult="pass"></job>
<tester name="tester1" lane="1" version="1.10"></tester>
<tests performed="2006-04-13 13:45:06" cycletime="76.3" faultcode="0001" faultmessage="helpful message">
<test name="continuity" result="pass" value="1" status="1" expectedvalue=”1”  lowerlimit="" upperlimit="" units="" ></test>
<test name="straingage" result="pass" value="5.67" expectedvalue=”5.53” status="1" lowerlimit="4.23" upperlimit="6.21" units="volts"></test>
</tests>
</result>
 
There is an example illustrating how to use all the major memebers of the XmlTextWriter. (You only concentrate on the methods WriteStartDocument(), WriteStartElement(), WriteAttributeString() and their corresponding WriteEnd...() parts. For the rest, you may or may not understand the concepts.)
Integrate it into your existing code where hard-coded data are replaced by the variables which hold the data.
 
I see the examples, and see how to write an XML file. Can I just build a string in VB and write it to the MQ? I did try it and it was encapsulated in <string> </string> tags.
 
Here's a quickie procedure that makes an XML doc, writes it to a text file, opens it back up and displays the contents in a messagebox. In practice you'll probably want to replace the file with a stream.

Code:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click

		[green]' file to save the xml document[/green]
		Dim SaveFile As String = "TestFile.xml"

		[green]' create the XML document[/green]
		Dim xDoc As New XmlDataDocument()

		[green]' create the declaration line[/green]
		Dim xDecl As XmlNode = xDoc.CreateXmlDeclaration("1.0", "utf-8", "no")

		[green]' create 3 elements to be used as the root (MyRoot),[/green] 
		[green]' a child (ChildElement) and an attribute (Attribute1)[/green]
		Dim xRoot As XmlElement = xDoc.CreateElement("MyRoot")
		Dim xChild As XmlElement = xDoc.CreateElement("ChildElement")
		Dim xAttr1 As XmlAttribute = xDoc.CreateAttribute("Attribute1")

		[green]' assign a value to the Attribute1[/green]
		xAttr1.Value = "Pat"

		[green]' add Attribute1 to the child node[/green]
		xChild.Attributes.Append(xAttr1)

		[green]' add the child node to the root[/green]
		xRoot.AppendChild(xChild)

		[green]' add the declaration and root node to the XML document[/green]
		xDoc.AppendChild(xDecl)
		xDoc.AppendChild(xRoot)

		[green]' save the XML file to disk[/green]
		xDoc.Save(SaveFile)

		[green]' open the file[/green]
		Dim xRead As IO.TextReader = New IO.StreamReader(SaveFile)

		[green]' read the whole XML doc an display it in a messagebox[/green]
		MessageBox.Show(xRead.ReadToEnd)


	End Sub

One thing to remember, XML documents are built from the inside out. It's much easier to to group all the code for each node together and then add them to the overall doc at the end. So create the Result, Jobs, Tester, Tests and test nodes. Then create the attributes for each and add them to the node they belong to. In the case of the Test nodes, add the attributes to each Test node, then add each Test node to the Tests node, and finally add the Tests node to the Result node.

I haven't worked with this stuff in a long time, but the application I dug up uses this to create the root node. The 3rd argument is the path to the schema file. It can included in the folder with your application, somewhere on your network or on a web host.

Code:
.AppendChild(.CreateDocumentType("RootName", Nothing, "Schema Path", Nothing))
 
[1] I am not sure if the op has taken lesson from the documentation referred to and made progress to a stage as said in the latest post _or_ he knows already all that and cannot handle the "format" and now string output? It is all unreasonably discontinuous in the message. It all very strange in suddenly mention something like <string></string>.

[1.1] In the referenced documentation, the .InnerXml will give you back a string so that you can send to whereever you want. It has persisted the xml document as an intermediate step. But if that "file" as the op mentioning all the time before the last is useful to him, that is not a handicap to the efficiency, instead it is a merit. So I don't understand why it is all the time a moving target as to the "question", suddenly he knows how to do it and suddenly not in writing the desired message in xml document.

[2] If you want to bypass the persistent xml document (the message) to a file and want to directly output to a stream or to a string, this is how you can do. I detail all the intermediate steps of constructing the message just to make sure you "know" actually how to do it. I make the illustration in c#. It can be translated to vb.net practically word-for-word.
[tt]
MemoryStream ms=new MemoryStream();
XmlTextWriter writer = null;
writer = new XmlTextWriter(ms, Encoding.UTF8);
writer.Formatting = Formatting.Indented;
writer.WriteStartDocument();
writer.WriteStartElement("result");
writer.WriteStartElement("job");
writer.WriteAttributeString("bsn", "123456");
writer.WriteAttributeString("barcode", "D1234567X01");
writer.WriteAttributeString("jobtype", "driver");
writer.WriteAttributeString("overallresult", "pass");
writer.WriteEndElement();

writer.WriteStartElement("tester");
writer.WriteAttributeString("name", "tester1");
writer.WriteAttributeString("lane", "1");
writer.WriteAttributeString("version", "1.10");
writer.WriteEndElement();

writer.WriteStartElement("tests");
writer.WriteAttributeString("performed", "2006-04-13 13:45:06");
writer.WriteAttributeString("cycletime", "76.3");
writer.WriteAttributeString("faultcode", "0001");
writer.WriteAttributeString("faultmessage", "helpful message");

writer.WriteStartElement("test");
writer.WriteAttributeString("name", "continuity");
writer.WriteAttributeString("result", "pass");
writer.WriteAttributeString("value", "1");
writer.WriteAttributeString("status", "1");
writer.WriteAttributeString("expectedvalue", "1");
writer.WriteAttributeString("lowerlimit", "");
writer.WriteAttributeString("upperlimit", "");
writer.WriteAttributeString("units", "");
writer.WriteEndElement();

writer.WriteStartElement("test");
writer.WriteAttributeString("name", "staingage");
writer.WriteAttributeString("result", "pass");
writer.WriteAttributeString("value", "5.67");
writer.WriteAttributeString("status", "1");
writer.WriteAttributeString("expectedvalue", "5.53");
writer.WriteAttributeString("lowerlimit", "4.23");
writer.WriteAttributeString("upperlimit", "6.21");
writer.WriteAttributeString("units", "volts");
writer.WriteEndElement();

writer.WriteEndElement(); //tests
writer.WriteEndElement(); //result
writer.WriteEndDocument();
writer.Flush();

ms.Position=0; //output memory stream answer available here
StreamReader sr=new StreamReader(ms);
string s=sr.ReadToEnd(); //output string answer available here

writer.Close();
[/tt]
 
tsuji,

First off, thank you for the time that you are putting into this. Please excuse my lack of knowing what to write. I am having problems understanding how everything works. I will try to be real explicit in this post.

My ultimate task is to receive a message in a message queue on the local machine, perform an action and write results to a different message queue on the local machine. I have worked with .Net a fair amount, but I am mainly still a VB6 programmer and have been for a while. I am not new to programming, just to kind of to .Net and totally new to MSMQ.

What I have done is tried to write a string to the MQ, which is encapsulated in the <string></string> tags.

I have also tried to write to the MQ creating a class with public properties, creating an instance of the class and writing it to the MQ. When I do that the public properties in the class show up in the MQ encapsulated in the name of the class tags, not string. I can read the properties when I receive it by creating an instance of the class.

I am not sure how much more technically I know about that, but I could show my code as an example if you wanted.

So, when I say I know how to write to the MQ, I have been able to write to the MQ, but I don't understand how the XML is created and written to the MQ. I am under the assumption that it isn't a file that goes to the MQ, but a string. (I don't understand it.)

I will try to build a XML string with the example you gave. Can you please clear up when building a XML MQ message, with the results in the bottom code block in my first post, is it done by creating a file and sending it, sending it a string, or something else?

Thanks again, and I appreciate your effort and time on this. As I write this, I think that I am really missing how something basic works with the MQ.

I will post back after I try to create the XML string like your example.
 
Okay, Now I am getting somewhere. This is the code that I used to build the file XML file below it. I couldn't get the MemoryStream to work yet, but I will keep on working on it.

Now I guess for the big question. Do I use the memory stream and put it in the message queue and how do I get it to the MQ?

(more below code)

Code:
 Private Sub Button5_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button5.Click
        Dim filename As String = "sampledata.xml"
        Dim writer As New XmlTextWriter(filename, Nothing)

        'Use indenting for readability.
        writer.Formatting = Formatting.Indented

        writer.WriteStartElement("result")
        writer.WriteStartElement("job")
        writer.WriteAttributeString("bsn", "123456")
        writer.WriteAttributeString("barcode", "D1234567X01")
        writer.WriteAttributeString("jobtype", "driver")
        writer.WriteAttributeString("overallresult", "pass")
        writer.WriteEndElement()

        writer.WriteStartElement("tester")
        writer.WriteAttributeString("name", "tester1")
        writer.WriteAttributeString("lane", "1")
        writer.WriteAttributeString("version", "1.10")
        writer.WriteEndElement()

        writer.WriteStartElement("tests")
        writer.WriteAttributeString("performed", "2006-04-13 13:45:06")
        writer.WriteAttributeString("cycletime", "76.3")
        writer.WriteAttributeString("faultcode", "0001")
        writer.WriteAttributeString("faultmessage", "helpful message")

        writer.WriteStartElement("test")
        writer.WriteAttributeString("name", "continuity")
        writer.WriteAttributeString("result", "pass")
        writer.WriteAttributeString("value", "1")
        writer.WriteAttributeString("status", "1")
        writer.WriteAttributeString("expectedvalue", "1")
        writer.WriteAttributeString("lowerlimit", "")
        writer.WriteAttributeString("upperlimit", "")
        writer.WriteAttributeString("units", "")
        writer.WriteEndElement()

        writer.WriteStartElement("test")
        writer.WriteAttributeString("name", "staingage")
        writer.WriteAttributeString("result", "pass")
        writer.WriteAttributeString("value", "5.67")
        writer.WriteAttributeString("status", "1")
        writer.WriteAttributeString("expectedvalue", "5.53")
        writer.WriteAttributeString("lowerlimit", "4.23")
        writer.WriteAttributeString("upperlimit", "6.21")
        writer.WriteAttributeString("units", "volts")
        writer.WriteEndElement()

        writer.WriteEndElement()    'tests
        writer.WriteEndElement()   'result

        'Write the XML to file and close the writer.
        writer.Flush()
        writer.Close()

        'Read the file back in and parse to ensure well formed XML.
        Dim doc As New XmlDocument()
        'Preserve white space for readability.
        doc.PreserveWhitespace = True
        'Load the file.
        doc.Load(filename)

        'Write the XML content to the console.
        Console.Write(doc.InnerXml)
    End Sub

Code:
- <result>
  <job bsn="123456" barcode="D1234567X01" jobtype="driver" overallresult="pass" /> 
  <tester name="tester1" lane="1" version="1.10" /> 
- <tests performed="2006-04-13 13:45:06" cycletime="76.3" faultcode="0001" faultmessage="helpful message">
  <test name="continuity" result="pass" value="1" status="1" expectedvalue="1" lowerlimit="" upperlimit="" units="" /> 
  <test name="staingage" result="pass" value="5.67" status="1" expectedvalue="5.53" lowerlimit="4.23" upperlimit="6.21" units="volts" /> 
  </tests>
  </result>

After that, which I will still be working on is I have to pick up a message in the MQ that I am told looks like this. How do I pull the values out of it?

Code:
<request>
<job bsn="1234567" barcode="D1234567X01" jobtype="driver" message="AN3 8-Way Pwr" testmask="YNYNYNN" />
<job bsn="1234567" barcode="P1234567X01" jobtype="passenger" message="AN3 Manual" testmask="NYNYNYY" />
</request>
 
Does this work for a memory stream? Below are the results that opened in the msgbox.

Code:
   Private Sub Button8_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button8.Click
        Dim memory_stream As New MemoryStream()
        Dim writer As New XmlTextWriter(memory_stream, System.Text.Encoding.UTF8)
        Dim strXML As String

        writer.Formatting = Formatting.Indented
        writer.WriteStartDocument(True)
        writer.WriteStartElement("retest")
        writer.WriteEndElement()
        writer.WriteEndDocument()
        writer.Flush()
        Dim stream_reader As New StreamReader(memory_stream)
        memory_stream.Seek(0, SeekOrigin.Begin)
        strXML = stream_reader.ReadToEnd()
        writer.Close()

        MsgBox(strXML)
    End Sub

Code:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<retest />
 
Why do you ask? Is it not working as far as the xml part is concerned? Why do you use MsgBox() vb6- leftover? Use MessageBox.Show() instead.
 
Yes, the XML works in the message box. (I will use the .Net MessageBox.Show.) I guess the only part now that I am struggling with is extracting the values from a received MQ message and if I am sending the XML correctly to the MQ.

Have you used MSMQ before? I am sending the XML as a string to the queue. In the queue it is encapsulated in the string tags, which I assume is the incorrect way of doing it.
 
Well, I ended up figuring everything out thanks to all your help. It ended up being a little more simple in the end compared to how complicated it was at one point.

I ended up using the BodyStream of the MQ. Thanks again for all of your help.

-UC
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top