无法解析XML:预期的空白

时间:2018-04-16 21:33:43

标签: xml vba serverxmlhttp

我有一个简单的VBA功能,可以向远程服务器发送POST。帖子正文是一个XML文档。

Sub testmessage()
Dim sXML As String, sURL As String, sResponse As String
Dim WinHttpReq As Object

Set WinHttpReq = CreateObject("MSXML2.ServerXMLHTTP")

sXML = "<?xml version=""1.0"" encoding=""ISO-8859-1""?>"
sXML = sXML & "<!DOCTYPE pnet_imessage_send PUBLIC ""-//PeopleNet//pnet_imessage_send"""
sXML = sXML & " ""http://open.peoplenetonline.com/dtd/pnet_imessage_send.dtd""> "
sXML = sXML & "<pnet_imessage_send>"
sXML = sXML & "  <cid>20</cid>"
sXML = sXML & "  <pw>password</pw>"
sXML = sXML & "  <vehicle_number>123</vehicle_number>"
sXML = sXML & "  <deliver>now</deliver>"
sXML = sXML & "  <freeform_message>This is Tim's test message.</freeform_message>"
sXML = sXML & "</pnet_imessage_send>"

'Test url'
'sURL = "https://open.pfmlogin.com/scripts/postp.dll"

'Live url
sURL = "https://oi.pfmlogin.com/scripts/open.dll"

WinHttpReq.Open "POST", sURL, False
WinHttpReq.setRequestHeader "Content-Type", "application/x-www-form-urlencoded;Charset=ISO-8859-1"
WinHttpReq.Send sXML
sResponse = WinHttpReq.responseText

Debug.Print sResponse
End Sub

sXML包含:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE pnet_imessage_send PUBLIC "-//PeopleNet//pnet_imessage_send" 
  "http://open.peoplenetonline.com/dtd/pnet_imessage_send.dtd"> 
<pnet_imessage_send>
  <cid>20</cid>
  <pw>password</pw>
  <vehicle_number>123</vehicle_number>
  <deliver>now</deliver>
  <freeform_message>This is Tim's test message.</freeform_message> 
</pnet_imessage_send>

如果我使用Chrome的Postman plugin发送此邮件,则会毫无问题地处理。使用VBA代码发布时,它会返回错误XML failed to parse. The reported error was: File: . Line: 1 Col: 19 Error: Whitespace expected at Line: 1 Position: 19

如果我将数据发布到测试网址(它只是弹回发布到它的任何内容),它会显示如下:

<?xml version="1.0"
encoding="ISO-8859-1"
><!DOCTYPE pnet_imessage_send PUBLIC "-//PeopleNet//pnet_imessage_send"
http://open.peoplenetonline.com/dtd/pnet_imessage_send.dtd

我认为服务器没有将换行符视为空格,导致XML解析器看起来像这样:<?xml version="1.0"encoding="ISO-8859-1">(&#34; 1.0&#34;和编码之间没有空格)。 Postman制作的帖子没有意外的换行符。如果没有VBA破解序言,我怎样才能发布这些数据?

1 个答案:

答案 0 :(得分:1)

这个答案归功于@TimWilliams。找一个他的帖子,如果它对你有帮助就给它+1。

正如他和@Chillin指出的那样,表单数据需要进行url编码(或以保留空格的方式进行编码...... HTML编码可能也有效,但我没有尝试过)。只需将请求标头设置为application/xml,就不会保留空白。

我在这篇SO帖子中使用了以下代码:How can I URL encode a string in Excel VBA?(如果这对你有所帮助,那就去给它+1)

Public Function URLEncode( _
   StringVal As String, _
   Optional SpaceAsPlus As Boolean = False _
) As String

  Dim StringLen As Long: StringLen = Len(StringVal)

  If StringLen > 0 Then
    ReDim result(StringLen) As String
    Dim i As Long, CharCode As Integer
    Dim Char As String, Space As String

    If SpaceAsPlus Then Space = "+" Else Space = "%20"

    For i = 1 To StringLen
      Char = Mid$(StringVal, i, 1)
      CharCode = Asc(Char)
      Select Case CharCode
        Case 97 To 122, 65 To 90, 48 To 57, 45, 46, 95, 126
          result(i) = Char
        Case 32
          result(i) = Space
        Case 0 To 15
          result(i) = "%0" & Hex(CharCode)
        Case Else
          result(i) = "%" & Hex(CharCode)
      End Select
    Next i
    URLEncode = Join(result, "")
  End If
End Function

然后在连接我的sXML字符串之后调用此函数:

sXML = sXML & "   <freeform_message>This is Tim's test message.</freeform_message>"
sXML = sXML & "</pnet_imessage_send>"
sXML = "service=imessage_send&xml=" & URLEncode(sXML, False)

它就像一个魅力!