2

我在需要解析 SOAP 请求的家庭项目中遇到了一些困难。SOAP 是使用 gSOAP 生成的,其中包含带有特殊字符(如丹麦字母“æøå”)的字符串参数。

gSOAP 默认使用 UTF-8 编码构建 SOAP 请求,但不是以原始格式发送特殊字符(即特殊字符“æ”的字节 C3A6),而是发送我认为称为字符哈希引用的内容(即 195;¦)。

我不完全理解为什么 gSOAP 会这样做,因为我可以看到它已将传入的有效负载标记为 UTF-8 编码(内容类型:text/xml;charset=utf-8),但除此之外问题(我认为)。

无论如何,我猜 gSOAP 可能正在遵守传输规则,还是什么?

当我在 python 中使用 xml.dom.minidom.parseString() 解析来自 gSOAP 的请求时,我将元素值作为 unicode 对象得到,这很好,但字符哈希引用没有被解码为 UTF-8 字符代码。它对字符散列引用进行转义,但之后不对字符串进行解码。最后我有一个 UTF-8 编码的 unicode 字符串对象:

因此,如果字符串“æble”包含在 XML 中,它在请求中会如下所示:

"æble"

解析 XML 后,DOM 文本节点的数据成员中的 unicode 字符串如下所示:

u'\xc3\xa6ble'

我希望它看起来像这样:

u'\xe6ble'

我究竟做错了什么?我应该在解析 SOAP XML 之前对其进行转义,还是应该在其他地方寻找解决方案,也许是 gSOAP?

提前致谢。

最好的问候雅各布西蒙-加德

4

5 回答 5

1

æble实际上是æble

要在解析后得到预期的 Unicode 字符串u'\xe6ble',请求中的字符串应该是æble.

于 2011-01-12T00:11:31.650 回答
0

关于我的问题的更多细节。我正在创建的项目使用 wsgi。SOAP 请求是使用environ['wsgi.input'].read(). 它似乎总是返回一个原始字符串。我创建了一个对字符散列进行转义的函数:

def unescape_hash_char(req):
  pat = re.compile('&#(\d+);',re.M)
  parts = pat.split(req)
  a=0
  ret = ''
  for p in parts:
    if a%2:
      n = chr(int(p))
    else:
      n = p
    ret += n
    a+=1
  return ret

完成此操作后,我解析 XML 并得到预期的结果。

我仍然想知道您的想法,以及它是否是一个好的解决方案。我也写了这个函数,因为我在标准 python 模块中找不到一个函数来完成这项工作,这样的函数存在吗?

最好的问候雅各布西蒙-加德

于 2011-01-11T23:56:01.147 回答
0

以下是如何取消转义这些东西:http ://effbot.org/zone/re-sub.htm#unescape-html

然而,主要问题是你和/或这个“gSOAP”(URL,请)正在做什么......

您的示例字符是 LATIN SMALL LIGATURE AE (U+00E6)。正如您所说,以 UTF-8 编码,这是\xc3\xa6. 0xc3 == 195 和 0xa6 == 166。0xe6 == 230。逃避你的角色应该产生'æ',而不是'æ'

但是,它似乎首先编码为 UTF-8,然后进行转义。

您需要做的是向我们详细展示您正在使用的代码以及诊断打印(使用 repr() 函数,以便我们可以看到过程中涉及的每个对象的类型str和明确表示的内容) unicode. 还提供您正在使用的 gSOAP API 的文档。

在接收端,请向我们展示您收到的原始 XML 的 repr()。

编辑以回应对另一个答案的此评论:“”“问题是 minidom.parseString() 在解码为 un​​icode 之前似乎没有对字符哈希表示进行转义。”“”

它(和任何其他 XML 解析器){不会,不能,也不能}在解码之前对数字字符引用或预定义的字符实体进行转义。

(1) 逃跑"&#60;""<"炸毁

(2) 你会逃避"&#256"什么?"\xc4\x80"?

(3) 如果编码是 UTF-16xx,它怎么能不转义?

于 2011-01-12T00:15:20.533 回答
0

注意

In [5]: 'æ'.encode('utf-8')
Out[5]: '\xc3\xa6'

所以我们有 unicode 对象u'\xc3\xa6',我们真的想要字符串对象'\xc3\xa6'。可以使用raw-unicode-escape编解码器执行此转换:

In [1]: text=u'\xc3\xa6'
In [2]: text.encode('raw-unicode-escape')
Out[2]: '\xc3\xa6ble'

In [3]: text.encode('raw-unicode-escape').decode('utf-8')
Out[3]: u'\xe6'

In [4]: print(text.encode('raw-unicode-escape').decode('utf-8'))
æ
于 2011-01-12T00:25:24.853 回答
0

除非有人能告诉我 gSOAP 没有生成有效的编码 SOAP XML:(请参阅http://pastebin.com/raw.php?i=9NS7vCMB或下面的代码块)除了在解析之前取消转义字符哈希引用之外,我没有其他解决方案XML。

当然,正如 John Machin 所指出的,我不能取消转义 XML 控制字符,如“<”和“>”。

<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:ns1="urn:ShopService"><SOAP-ENV:Body SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><ns1:createCompany><company-code>DK-123</company-code><name>&#195;&#166;ble</name></ns1:createCompany></SOAP-ENV:Body></SOAP-ENV:Envelope>

/雅各布

于 2011-01-12T08:29:40.653 回答