4

XML形式でデータを投稿する必要があります。サーバーは特定のxml形式を受け入れます。私は手作業でxmlを書きたくありません。私がしたいのは、それを作成し、NSMutableDictionaryそれをNSMutableDictionaryXMLに変換することです。

私はこれを使用します:

[NSPropertyListSerialization dataWithPropertyList:data format:NSPropertyListXMLFormat_v1_0 options:0

サンプルの返品は次のとおりです。

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0">
<dict>
<key>email</key>
<string>me@n.net</string>
<key>invoice_date</key>
<string>2012-10-11T10:35:09Z</string>
<key>invoice_lines</key>
<array>
    <dict>
        <key>product_id</key>
        <integer>1021493</integer>
        <key>quantity</key>
        <real>1</real>
        <key>retail_price</key>
        <real>110</real>
    </dict>
</array>
<key>payments</key>
<array>
    <dict>
        <key>amount</key>
        <real>288.5</real>
    </dict>
    <dict>
        <key>payment_type_id</key>
        <integer>1</integer>
    </dict>
</array>

上記の形式はサーバーから読み取ることができません。

サーバーには、このようなxmlフィードが必要です。

  <invoice>
      <invoice_date>2012-10-11T10:35:09Z</invoice_date>
      <email>me@n.net</email>
        <invoice_lines type="array">
         <invoice_line>
       <product_id>1021505</product_id>
       <quantity>1</quantity>
       <retail_price>45</retail_price>
     </invoice_line>
  </invoice_lines>
  <payments type="array">
    <payment>
      <amount>288.5</amount>
     </payment>
  </payments>

</invoice>

上記のxmlを?から生成することは可能NSDictionaryですか?

ありがとう!

4

4 に答える 4

4

簡単な答えは次のとおりです。いいえ、Cocoaライブラリにはこれを行うための組み込み機能はありません。

解析ではなく記述を行っており、おそらく可能なタグの限られた範囲を扱っているため、XMLを出力するコードは実際にはそれほど複雑ではありません。これは、Invoiceオブジェクトの次のような単純なメソッドである必要があります。

- (NSString*) postStringInXMLFormat
{
    NSMutableString* returnValue = [[NSMutableString alloc] init];
    if([self email])
    {
        [returnValue appendString:@"<email>"];
        [returnValue appendString:[self email]];
        [returnValue appendString:@"</email>"];
    }
    if([self invoice_date])
    ...

等々。最後に戻る

[NSString stringWithString:returnValue]

このプロセスを一般化しようとするサードパーティのプロジェクトはたくさんあります。それらのいくつかはこの回答にリストされています:

iPhoneアプリ用のXMLシリアル化ライブラリ

しかし、サーバー側が認識できる単一の安定したフォーマットを作成するだけで、変換するエンティティの数がばかげていない場合は、独自のフォーマットを作成する方がおそらく手間がかかりません。

于 2012-11-05T19:05:49.360 に答える
3

辞書をXMLの文字列に変換する再帰的な方法は次のとおりです。辞書、配列、文​​字列を処理します。ディクショナリキーはXMLタグであり、ディクショナリオブジェクトはツリーの値または子アイテムとして使用されます。配列の場合、配列内の各要素は同じタグを持つ同じ子レベルに配置されます。

- (NSString*)ConvertDictionarytoXML:(NSDictionary*)dictionary  withStartElement:(NSString*)startElement{
    NSMutableString *xml = [[NSMutableString alloc] initWithString:@""];
    [xml appendString:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
    [xml appendString:[NSString stringWithFormat:@"<%@>",startElement]];
    [self convertNode:dictionary withString:xml andTag:nil];
    [xml appendString:[NSString stringWithFormat:@"</%@>",startElement]];
    NSString *finalXML=[xml stringByReplacingOccurrencesOfString:@"&" withString:@"&amp;"];
    NSLog(@"%@",xml);
    return finalXML;
}

- (void)convertNode:(id)node withString:(NSMutableString *)xml andTag:(NSString *)tag{
    if ([node isKindOfClass:[NSDictionary class]] && !tag) {
    NSArray *keys = [node allKeys];
    for (NSString *key in keys) {
        [self convertNode:[node objectForKey:key] withString:xml andTag:key];
    }
    }else if ([node isKindOfClass:[NSArray class]]) {
        for (id value in node) {
             [self convertNode:value withString:xml andTag:tag];
        }
    }else {
        [xml appendString:[NSString stringWithFormat:@"<%@>", tag]];
        if ([node isKindOfClass:[NSString class]]) {
        [xml appendString:node];
        }else if ([node isKindOfClass:[NSDictionary class]]) {
            [self convertNode:node withString:xml andTag:nil];
        }
        [xml appendString:[NSString stringWithFormat:@"</%@>", tag]];
    }
}
于 2015-12-09T21:43:51.087 に答える
2

ライブラリを使用しない場合、または追加のカスタマイズが必要な場合:

- (NSString*)convertDictionaryToXML:(NSDictionary*)dictionary withStartElement:(NSString*)startElement
{
    return [self convertDictionaryToXML:dictionary withStartElement:startElement isFirstElement:YES];
}

- (NSString*)convertDictionaryToXML:(NSDictionary*)dictionary withStartElement:(NSString*)startElement isFirstElement:(BOOL) isFirstElement
{
    NSMutableString *xml = [[NSMutableString alloc] initWithString:@""];
    NSArray *arr = [dictionary allKeys];
    if (isFirstElement)
    {
        [xml appendString:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"];
    }
    [xml appendString:[NSString stringWithFormat:@"<%@>\n", startElement]];
    for(int i=0; i < [arr count]; i++)
    {
        NSString *nodeName = [arr objectAtIndex:i];
        id nodeValue = [dictionary objectForKey:nodeName];
        if([nodeValue isKindOfClass:[NSArray class]])
        {
            if([nodeValue count]>0)
            {
                for(int j=0;j<[nodeValue count];j++)
                {
                    id value = [nodeValue objectAtIndex:j];
                    if([value isKindOfClass:[NSDictionary class]])
                    {
                        [xml appendString:[self convertDictionaryToXML:value withStartElement:nodeName isFirstElement:NO]];
                    }
                }
            }
        }
        else if([nodeValue isKindOfClass:[NSDictionary class]])
        {
            [xml appendString:[self convertDictionaryToXML:nodeValue withStartElement:nodeName isFirstElement:NO]];
        }
        else
        {
            if([nodeValue length]>0){
                [xml appendString:[NSString stringWithFormat:@"<%@>",nodeName]];
                [xml appendString:[NSString stringWithFormat:@"%@",[dictionary objectForKey:nodeName]]];
                [xml appendString:[NSString stringWithFormat:@"</%@>\n",nodeName]];
            }
        }
    }

    [xml appendString:[NSString stringWithFormat:@"</%@>\n",startElement]];

    NSString *finalxml=[xml stringByReplacingOccurrencesOfString:@"&" withString:@"&amp;"];

    return finalxml;
}

これを次のように呼びます。

NSString *xmlString = [self convertDictionaryToXML:data withStartElement:startElementName];
于 2015-02-25T00:08:24.680 に答える
0

@RemembranceNNからの回答を先取りして、Swiftに変換しました。

extension Dictionary {
    func getXML(withStartElement startElement: String) -> String {
        (self as NSDictionary).getXML(withStartElement: "message")
    }
}

extension NSDictionary {
    func getXML(withStartElement startElement: String, addLeafChildAsAttributes attrFlag: Bool, dontCreateNameSpaceChilds nsFlag: Bool) -> String {
        var string = ""
        var startTag = "<\(startElement)"
        var tagValue = ""
    
        for (key, value) in self {
            if let arr = value as? NSArray {
                for item in arr {
                    if let itemDict = item as? NSDictionary {
                        tagValue.append(itemDict.getXML(withStartElement: "\(key)", addLeafChildAsAttributes: attrFlag, dontCreateNameSpaceChilds: nsFlag))
                    } else {
                        tagValue.append("<\(key)>")
                        tagValue.append("\(item)")
                        tagValue.append("</\(key)>")
                    }
                }
            } else if let nestedDict = value as? NSDictionary {
                tagValue.append(nestedDict.getXML(withStartElement: "\(key)", addLeafChildAsAttributes: attrFlag, dontCreateNameSpaceChilds: nsFlag))
            } else {
                if attrFlag || (nsFlag && "\(key)" == "xmlns") {
                    startTag.append(" \(key)=\"\(value)\"")
                }
                if !nsFlag || "\(key)" != "xmlns" {
                    tagValue.append("<\(key)>")
                    tagValue.append("\(value)")
                    tagValue.append("</\(key)>")
                }
            }
        }
        startTag.append(">")
        string.append(startTag)
        string.append(tagValue)
        string.append("</\(startElement)>")
        return string
    }
}
于 2022-01-14T14:08:35.540 に答える