0

We are working on integrating QBXML with an application of ours and all is working pretty well until today when we attempted to create a new NonInventoryItemPart using the WebConnector. Below is the XML we sent

<?xml version="1.0"?>
<?qbxml version="10.0"?>
<QBXML>
    <QBXMLMsgsRq onError="continueOnError">
        <ItemNonInventoryAddRq requestID="5468-22415">
            <ItemNonInventoryAdd>
                <Name>C-1531</Name>
                <IsActive>false</IsActive>
                <SalesAndPurchase>
                    <SalesDesc>Sumo Rucsac (225 lb +)… Single</SalesDesc>
                    <IncomeAccountRef>
                        <FullName>P/A - Over the Counter</FullName>
                    </IncomeAccountRef>
                    <ExpenseAccountRef>
                        <FullName>C/S P/A - Over the Counter</FullName>
                    </ExpenseAccountRef>
                </SalesAndPurchase>
            </ItemNonInventoryAdd>
        </ItemNonInventoryAddRq>
    </QBXMLMsgsRq>
</QBXML>

The response in the connection log was the well known error message of

0x80040400 :QuickBooks found an error when parsing the provided XML text

After some trial and error and internet searched, the SalesDesc inner text is what is causing the error, specifically (I think) the plus sign. If we change the SalesDesc inner text to Sumo Rucsac 225 lb Single, this item is created successfully.

In C#, we need the ability to properly encode the request so that if other non acceptable characters appear, we can handle them appropriately. However, I cannot find any good details on what characters (encoding) are accepted nor exactly what type of encoding to use so we are more bullet-proof in the future (eg UrlEncoding, HtmlEncoding...custom function?). I could maintain a list of characters to remove, but that seems like it would lead to a maintenance nightmare.

EDIT - Thanks to @Amy below, the problem was narrowed down to .... For a temporary fix, we are using item.Name.Replace("...", ".."); to generate the inner text for our items. I still think we will need a more robust character handling going forward, but since its not + or ( or ), I feel a bit more comfortable with this band-aid for now.

Tommy
  • 39,592
  • 10
  • 90
  • 121
  • 1
    Try wrapping it in a `CDATA` element, maybe? The `…` looks suspect. –  Jun 16 '18 at 15:58
  • @Amy - Thanks for the input! I tried the CDATA tag, but I don't think QBXML likes that very much. But...your pointing to the ellipsis yielded some good results. It turns out it was not the parenthesis or plus sign, but `...` as only changing it to `..` worked as it should. Interesting as this data comes from a text file, so its not an HTML ellipse entity or anything like that...? I guess that specific combination of characters has a special meaning even if it is literally three periods in a row. – Tommy Jun 16 '18 at 16:23
  • I have a hypothesis: the QBXML reader isn't treating the XML as UTF-8. Maybe try specifying the encoding in the XML element? (I don't know about the QBXML element). I have no other constructive ideas. Maybe the software reading the QBXML doesn't understand unicode strings? –  Jun 16 '18 at 16:32
  • @Amy - that's another good idea. Admittedly, I am weak on encoding and XML so I'm learning on the fly! – Tommy Jun 16 '18 at 16:34
  • How are you creating this XML? Using some XML aware component or plain string(builder)? A component would know about encoding special characters. – Hans Kesting Jun 16 '18 at 16:39
  • Info on the ellipsis character: http://graphemica.com/%E2%80%A6 –  Jun 16 '18 at 16:41
  • @HansKesting - I am using the .NET XML document objects to create this XML - such as `var inputXmlDoc = CreateBaseQbXml(); var qbXml = inputXmlDoc.CreateElement("QBXML"); inputXmlDoc.AppendChild(qbXml);` Specifically, the call for the item in question is `var desc = inputXmlDoc.CreateElement("SalesDesc"); desc.InnerText = item.Name.Replace("...", "..");` - note the new replace addition :) – Tommy Jun 16 '18 at 16:49

1 Answers1

1

The QuickBooks SDK doesn't handle special characters very well even if you specify utf8 encoding. You can sometimes escape characters to get it to import:

<?xml version="1.0"?>
<?qbxml version="10.0"?>
<QBXML>
    <QBXMLMsgsRq onError="continueOnError">
        <ItemNonInventoryAddRq requestID="5468-22415">
            <ItemNonInventoryAdd>
                <Name>C-1531</Name>
                <IsActive>false</IsActive>
                <SalesAndPurchase>
                    <SalesDesc>Sumo Rucsac (225 lb +)&#8230; Single</SalesDesc>
                    <IncomeAccountRef>
                        <FullName>P/A - Over the Counter</FullName>
                    </IncomeAccountRef>
                    <ExpenseAccountRef>
                        <FullName>C/S P/A - Over the Counter</FullName>
                    </ExpenseAccountRef>
                </SalesAndPurchase>
            </ItemNonInventoryAdd>
        </ItemNonInventoryAddRq>
    </QBXMLMsgsRq>
</QBXML>

The response will not show the correctly encoded character, but it does show correctly in QuickBooks:

<?xml version="1.0" ?>
<QBXML>
   <QBXMLMsgsRs>
      <ItemNonInventoryAddRs requestID="5468-22415" statusCode="0" statusSeverity="Info" statusMessage="Status OK">
         <ItemNonInventoryRet>
            <ListID>80000005-1530119757</ListID>
            <TimeCreated>2018-06-27T13:15:57-05:00</TimeCreated>
            <TimeModified>2018-06-27T13:15:57-05:00</TimeModified>
            <EditSequence>1530119757</EditSequence>
            <Name>C-1531</Name>
            <FullName>C-1531</FullName>
            <IsActive>false</IsActive>
            <Sublevel>0</Sublevel>
            <SalesAndPurchase>
               <SalesDesc>Sumo Rucsac (225 lb +)&#133; Single</SalesDesc>
               <SalesPrice>0.00</SalesPrice>
               <IncomeAccountRef>
                  <ListID>80000020-1530119204</ListID>
                  <FullName>P/A - Over the Counter</FullName>
               </IncomeAccountRef>
               <PurchaseCost>0.00</PurchaseCost>
               <ExpenseAccountRef>
                  <ListID>80000021-1530119611</ListID>
                  <FullName>C/S P/A - Over the Counter</FullName>
               </ExpenseAccountRef>
            </SalesAndPurchase>
         </ItemNonInventoryRet>
      </ItemNonInventoryAddRs>
   </QBXMLMsgsRs>
</QBXML>
Hpjchobbes
  • 1,309
  • 1
  • 8
  • 11