我正在为iOS制作一个应用程序,它使用libxml2生成一些XML,后来用作SOAP请求。我编写了一个递归函数,它将NSDictionary作为参数,并根据其嵌套结构生成XML节点(我允许将NSDictionary设置为另一个NSDictionary中的值)。我遇到了一个不够的情况,我想手动创建一些XML然后把它放在某个节点内。我发现使用我当前的代码是不可能的。
libxml2会自动将所有特殊字符(包括显式必需的<
和>
)替换为HTML实体通讯记录,例如<
和>
。即使我在网上看到我需要手动编码它们 - 使用xmlEncodeEntitiesReentrant。我很无能为力。我需要做的就是暂时禁用该替换,以便将一些干净的XML代码放入节点中。
以下是我的应用程序来源的片段:
void generate_xml(xmlNodePtr root, NSDictionary *dict) {
for (NSString *key in dict) {
xmlNodePtr node = NULL;
id obj = [dict valueForKey:key];
if ([obj isKindOfClass:[NSDictionary class]]) {
node = xmlNewNode(NULL, BAD_CAST [key UTF8String]);
xmlAddChild(root, node);
generate_xml(node, obj);
} else if ([key isEqual:@"text"]) {
xmlNodeSetContent(root, BAD_CAST [obj UTF8String]);
} else if ([key isEqual:@"text_with_tags"]) {
//disable encoding the special characters and go on
xmlNodeSetContent(root, BAD_CAST [obj UTF8String]);
} else {
xmlNewProp(root, BAD_CAST [key UTF8String], BAD_CAST [obj UTF8String]);
}
}
}
- (NSData *)prepareRequestBody {
NSData *data = nil;
xmlDocPtr doc = NULL;
xmlNodePtr root = NULL;
xmlNodePtr node = NULL;
xmlNodePtr body = NULL;
char *buffer = NULL;
int length = 0;
doc = xmlNewDoc(BAD_CAST "1.0");
root = xmlNewNode(NULL, BAD_CAST "SOAP-ENV:Envelope");
xmlNewProp(root, BAD_CAST "xmlns:xsd", BAD_CAST "http://www.w3.org/2001/XMLSchema");
xmlNewProp(root, BAD_CAST "xmlns:xsi", BAD_CAST "http://www.w3.org/2001/XMLSchema-instance");
xmlNewProp(root, BAD_CAST "xmlns:SOAP-ENC", BAD_CAST "http://schemas.xmlsoap.org/soap/encoding/");
xmlNewProp(root, BAD_CAST "SOAP-ENV:encodingStyle", BAD_CAST "http://schemas.xmlsoap.org/soap/encoding/");
xmlNewProp(root, BAD_CAST "xmlns:SOAP-ENV", BAD_CAST "http://schemas.xmlsoap.org/soap/envelope/");
xmlDocSetRootElement(doc, root);
body = xmlNewChild(root, NULL, BAD_CAST "SOAP-ENV:Body", NULL);
node = xmlNewChild(body, NULL, BAD_CAST [[NSString stringWithFormat:@"m:%@", method] UTF8String], NULL);
xmlNewProp(node, BAD_CAST "xmlns:m", BAD_CAST [[url absoluteString] UTF8String]);
generate_xml(node, arguments);
xmlDocDumpMemoryEnc(doc, (xmlChar **)&buffer, &length, "UTF-8");
data = [NSData dataWithBytes:buffer length:length];
xmlFree(buffer);
xmlFreeDoc(doc);
return data;
}
有没有办法实现这个目标?
答案 0 :(得分:0)
我以一种不优雅的方式解决了它。我为!#LT#!
字符定义了自己的实体 - 例如<
。然后我简单地将使用这些字符集的字符串放入XML树中,并在libxml完成生成XML请求后立即将所有这些集合替换为适当的通信。到目前为止似乎已经完成了这项工作,但您必须记住检查所有用户输入字段中的自定义实体,以确保用户不会搞砸您的整个请求。