0

I have revised the question and included the code I have write so far for this question. Below is an example of what the output must look like to be compatible with the VeriFone MX915 Payment terminal. In this specific part, I am trying to send the POS register items to the display.

<TRANSACTION>
    <FUNCTION_TYPE>LINE_ITEM</FUNCTION_TYPE>
    <COMMAND>ADD</COMMAND>
    <COUNTER>1</COUNTER>
    <MAC> … </MAC>
    <MAC_LABEL>REG2</MAC_LABEL>
    <RUNNING_SUB_TOTAL>7.00</RUNNING_SUB_TOTAL>
    <RUNNING_TRANS_AMOUNT>7.42</RUNNING_TRANS_AMOUNT>
    <RUNNING_TAX_AMOUNT>0.42</RUNNING_TAX_AMOUNT>
    <LINE_ITEMS>
        <MERCHANDISE>
            <UNIT_PRICE>5.00</UNIT_PRICE>
            <DESCRIPTION>#1 Combo Meal</DESCRIPTION>
            <LINE_ITEM_ID>1695155651</LINE_ITEM_ID>
            <EXTENDED_PRICE>5.00</EXTENDED_PRICE>
            <QUANTITY>1</QUANTITY>
        </MERCHANDISE>
    </LINE_ITEMS>
</TRANSACTION>

The SDK supplied by VeriFone has made some of the methods needed to communicate with the device. So the following code has method calls and class level variables that are written but not included in the following example:

/// <summary>
        /// Send 1 or more items to the Verifone display.  Include subtotal, tax and total
 /// </summary>
 /// <param name="nSubTotal">Subtotal of transaction</param>
 /// <param name="nTax">Current Tax of transaction</param>
 /// <param name="nTotal">Total of transaction</param>
 /// <param name="UPC">Item Code</param>
 /// <param name="ShortDescription">Small description</param>
 /// <param name="nItemAmount">Item Amt</param>
 /// <param name="nQty">Quantity</param>
 /// <param name="nExtendedAmount">Quantity X Item Amt</param>
 /// <returns></returns>
        public bool AddLineItem(double nSubTotal, double nTax, double nTotal, Int32 nItemID, string UPC, string ShortDescription, double nItemAmount, Int32 nQty, double nExtendedAmount)
        {

            // get counter and calculate Mac
            var nextCounter = (++counter).ToString();
            var mac = PrintMacAsBase64(macKey, nextCounter);

            // build request
            var request = new XDocument();
            using (var writer = request.CreateWriter())
            {
                //populate the elements
                writer.WriteStartDocument();
                writer.WriteStartElement("TRANSACTION");
                writer.WriteElementString("FUNCTION_TYPE", "LINE_ITEM");
                writer.WriteElementString("COMMAND", "ADD");
                writer.WriteElementString("MAC_LABEL", macLabel);
                writer.WriteElementString("COUNTER", nextCounter);
                writer.WriteElementString("MAC", mac);
                writer.WriteElementString("RUNNING_SUB_TOTAL",nSubTotal.ToString("c"));
                writer.WriteElementString("RUNNING_TAX_AMOUNT",nTax.ToString("c"));
                writer.WriteElementString("RUNNING_TRANS_AMOUNT",nTotal.ToString("c"));

                //HERE IS WHERE I NEED TO WRITE THE CHILD ELEMENT(s):  

                //example below of what they or it would look like 
                //(collection of merchandise elements under Line_items)
                //I know this example will have only one item because of parameters

                /*
                <LINE_ITEMS>
                    <MERCHANDISE>
                        <LINE_ITEM_ID>10</LINE_ITEM_ID>
                        <DESCRIPTION>This is a dummy</DESCRIPTION>
                        <UNIT_PRICE>1.00</UNIT_PRICE>
                        <QUANTITY>1</QUANTITY>
                        <EXTENDED_PRICE>1.00</EXTENDED_PRICE>
                    </MERCHANDISE>
                </LINE_ITEMS>
                */

                writer.WriteEndElement();
                writer.WriteEndDocument();
            }

            // transmit to Point Solution and interrogate the response
            var responseXml = Send(address, port, request);


            //DO SOMETHING HERE WITH THE RESPONSE
            // validate that the RESULT_CODE came back a SUCCESS
            if ("-1" != responseXml.Element("RESPONSE").Element("RESULT_CODE").Value)
            {
                throw new Exception(responseXml.Element("RESPONSE").Element("RESULT_TEXT").Value ?? "unknown error");
            }
            return true;


        }

If any one can help me understand how to populate the child elements as indicated where I put comments in the code I will be very thankful.

Thanks to the moderators for requesting more information on this.

John Fischer
  • 318
  • 3
  • 8
  • There's probably tendy-hundred examples on SO if you look. Have you reviewed MS docs at all? https://msdn.microsoft.com/en-us/library/system.xml.xmlwriter(v=vs.110).aspx – Stinky Towel Aug 27 '16 at 19:59
  • I have read that specific and many others but where I am getting jammed up (and I am new admittedly) is on how to write the stuff below the using the XMLWriter class. Any hint would be gratefully received. Thanks. – John Fischer Aug 27 '16 at 21:40
  • To give directions we need to know where you're starting from and we don't know that. Does “I am getting jammed up ... on how to write the stuff below the ” mean that you have code that writes everything above that? Please show us that code. Or do you not know how to “write the stuff”? Can you write any C# code at all? You're really giving us nothing to go on here... – Dour High Arch Aug 27 '16 at 23:00
  • I edited the question and gave much more detail and examples of the code I have written. Thanks. – John Fischer Aug 28 '16 at 15:22

2 Answers2

1

I think using XmlSerializer is a good idea, maybe codes below could help you. XmlSerializer is more intuitive than XmlWriter to generate Xml. : )

using System;
using System.Collections.Generic;
using System.Xml.Serialization;

class Program
{
    static void Main(string[] args)
    {
        Transaction transaction = new Transaction();
        transaction.Function_Type = "LINE_ITEM";
        transaction.LineItems = new List<Merchandise>();
        transaction.LineItems.Add(new Merchandise() { UnitPrice = "5.00" });

        //Create our own namespaces for the output
        XmlSerializerNamespaces ns = new XmlSerializerNamespaces();

        //Add an empty namespace and empty value
        ns.Add("", "");

        using (XmlWriter writer = XmlWriter.Create(Console.Out, new XmlWriterSettings { OmitXmlDeclaration = true }))
        {
            new XmlSerializer(typeof(Transaction)).Serialize(writer, transaction, ns);
        }

        Console.Read();
    }
}

[XmlRoot("TRANSACTION")]
public class Transaction
{
    [XmlElement("FUNCTION_TYPE")]
    public string Function_Type { get; set; }

    [XmlArray("LINE_ITEMS")]
    [XmlArrayItem("MERCHANDISE")]
    public List<Merchandise> LineItems { get; set; }
}

[XmlRoot("MERCHANDISE")]
public class Merchandise
{
    [XmlElement("UNIT_PRICE")]
    public string UnitPrice { get; set; }
}

Results:
enter image description here

Arthas
  • 163
  • 1
  • 7
  • I really like your answer the best. Is there anyway to get the serializer to not print the version, encoding info at the top and for the transaction element not to contain the schema? – John Fischer Sep 01 '16 at 12:59
  • Hi @JohnFischer, I have edit my answer, hope these codes can help you : ) – Arthas Sep 02 '16 at 01:29
  • Hello @Arthas I get all of it working today and many thanks to your answer. I am now battling some other problems but nothing related to this post. I am doing a VeriFone MX915 integration project with a home grown Point of Sale program. It is challenging. Thanks again for your help. – John Fischer Sep 02 '16 at 22:19
0

You could use XmlDocument

    XmlDocument xmlDoc = new XmlDocument();

    XmlNode rootNode = xmlDoc.CreateElement("RootNode");
    xmlDoc.AppendChild(rootNode);

    foreach (Class objItem in classArray)
    {


        XmlNode firstNode= xmlDoc.CreateElement("First");
        XmlNode second= xmlDoc.CreateElement("Second");
        second.InnerText = objItem .Text;
        firstNode.AppendChild(second);

        rootNode.AppendChild(firstNode);
    }
    StringWriter stringWriter = new StringWriter();
    XmlTextWriter textWriter = new XmlTextWriter(stringWriter);
    xmlDoc.WriteTo(textWriter);
Slai
  • 22,144
  • 5
  • 45
  • 53