【问题标题】:libxml2 - xmlNodeSetContent and entities troublelibxml2 - xmlNodeSetContent 和实体问题
【发布时间】:2011-07-28 22:42:13
【问题描述】:

我正在为 iOS 创建一个应用程序,它使用 libxml2 生成一些 XML,这些 XML 稍后用作 SOAP 请求。我编写了一个递归函数,它以 NSDictionary 作为参数并根据其嵌套结构生成 XML 节点(我允许将 NSDictionary 设置为另一个 NSDictionary 中的值)。我遇到了一个不够的情况,我想手动创建一些 XML,然后将它放在某个节点内。我发现使用我当前的代码是不可能的。

libxml2 自动将所有特殊字符(包括显然必不可少的 <>)替换为它们的 HTML 实体对应符 - 例如 <>。即使我在网上读到我需要手动编码它们 - 使用 xmlEncodeEntitiesReentrant。我很无知。我需要做的就是暂时禁用该替换,以便将一些干净的 XML 代码放入节点中。

这是来自我的应用程序源的 sn-p:

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;
}

有没有办法做到这一点?

【问题讨论】:

    标签: html objective-c xml libxml2 entities


    【解决方案1】:

    我以一种不优雅的方式解决了它。我为< 字符定义了我自己的实体——比如!#LT#!。然后,我只需将使用此类字符集的字符串放入 XML 树中,并在 libxml 完成生成 XML 请求后立即将所有出现的这些字符集替换为其适当的对应对象。到目前为止似乎已经完成了这项工作,但您必须记住检查所有用户输入字段中的自定义实体,以确保用户不会搞砸您的整个请求。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多