2011-07-28 98 views
1

我正在爲iOS應用程序使用libxml2生成一些XML,稍後將其用作SOAP請求。我寫了一個遞歸函數,它將NSDictionary作爲參數,並根據其嵌套結構生成XML節點(我允許將NSDictionary設置爲另一個NSDictionary中的值)。我遇到了一個不夠的情況,我想手動創建一些XML,然後將其放入某個節點。我發現使用我當前的代碼是不可能的。libxml2 - xmlNodeSetContent和實體問題

libxml2會自動用它們的HTML實體記者(如&lt;&gt;)替代顯式必需的所有特殊字符,包括<>。即使我在網上閱讀過,我需要手動編碼它們 - 使用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

我用一種不太好的方式解決了它。我定義了我自己的實體,如<字符!#LT#!。然後,我簡單地將使用這些字符集的字符串放入XML樹中,並在libxml完成​​生成XML請求後立即用它們的適當通信者替換所有這些集的出現。似乎到目前爲止這項工作,但你必須記住檢查所有用戶輸入字段中的自定義實體,以確保用戶不會搞砸你的整個請求。