Я думаю, что более интересным вопросом является то, что представляет собой подходящую комбинацию вложенных NSArray
и NSDictionary
объектов коллекции, которые лучше всего представляют эту структуру в Objective-C. Затем, как только у вас есть это в вложенных объектах коллекции, вы можете использовать метод writeToFile
для автоматического создания файла plist.
Теперь вы говорите, что вам не нужен «массив для каждого тега с атрибутом». Во-первых, я бы не предложил массив, но я бы предложил словарь. Во-вторых, это именно то, что я думаю, вы хотите, последовательное, понятное представление для каждого тега. В-третьих, я предлагаю вам сделать это не только для тегов с атрибутами, но я могу даже сделать это для всех тегов.
Я не уверен, почему вы сказали, что не хотите использовать массив для каждого тега, но, хотя это может показаться неэффективным, оказывается, что это намного проще сделать, потому что тогда ваша структура будет в последовательный, простой в использовании формат.
Самое простое решение, чтобы иметь словарь для каждого элемента в источнике XML, один ключ будет @"value"
, а другой будет @"attributes"
(и вы могли бы опустить attributes
если бы не было ни одного).
Представьте себе следующий XML:
<produce>
<product>
<name language="English">Apple</name>
<price currency="USD">1.23</price>
<color>red</color>
</product>
<product>
<name language="English">Banana</name>
<price currency="USD">2.63</price>
<color>yellow</color>
</product>
</produce>
Я предлагаю вам есть множество продуктов, для которых каждый продукт является NSDictionary
с тремя ключами, name
, price
и color
. Значения для этих трех - это сами, NSDictionary
объектов, но с двумя ключами, value
и, при необходимости, attributes
. Таким образом, если вы собираетесь представить, что в результате серии вложенных объектов вручную в коде, он может выглядеть следующим образом (где, @[a, b, c]
является NSArray
и @{key1:value1, key2:value2}
является NSDictionary
):
NSArray *array = @[
@{
@"name":
@{
@"value" : @"Apple",
@"attributes" : @{@"language":@"English"}
},
@"price":
@{
@"value" : @1.23,
@"attributes" : @{@"currency":@"USD"}
},
@"color":
@{
@"value" : @"red"
}
},
@{
@"name":
@{
@"value" : @"Banana",
@"attributes" : @{@"language":@"English"}
},
@"price":
@{
@"value":@1.46,
@"attributes":@{@"currency":@"USD"}
},
@"color":@{@"value":@"yellow"}
}
];
Хотя это кажется сложным, это фактически невероятно прост в использовании. Если вы хотите второй объект, это будет array[1]
. Если вам нужен цвет этого второго объекта, это будет array[1][@"color"][@"value"]
. Если вам нужно имя языка первого объекта, это будет array[0][@"name"][@"attributes"][@"language"]
. После того, как вы начнете использовать эту структуру вложенных объектов коллекции, вы можете увидеть (а), почему я предпочитаю словари массивам; но также почему (б) я использую ту же структуру словаря, есть ли атрибут или нет, таким образом процесс извлечения значения всегда согласован.
Во всяком случае, если я теперь использовать метод writeToFile
, что происходит с возвращающим PLIST так:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>color</key>
<dict>
<key>value</key>
<string>red</string>
</dict>
<key>name</key>
<dict>
<key>attributes</key>
<dict>
<key>language</key>
<string>English</string>
</dict>
<key>value</key>
<string>Apple</string>
</dict>
<key>price</key>
<dict>
<key>attributes</key>
<dict>
<key>currency</key>
<string>USD</string>
</dict>
<key>value</key>
<real>1.23</real>
</dict>
</dict>
<dict>
<key>color</key>
<dict>
<key>value</key>
<string>yellow</string>
</dict>
<key>name</key>
<dict>
<key>attributes</key>
<dict>
<key>language</key>
<string>English</string>
</dict>
<key>value</key>
<string>Banana</string>
</dict>
<key>price</key>
<dict>
<key>attributes</key>
<dict>
<key>currency</key>
<string>USD</string>
</dict>
<key>value</key>
<real>1.46</real>
</dict>
</dict>
</array>
</plist>
Но хорошая вещь, я не должен написать Plist себя. Я просто загружаю XML в свою структуру вложенных массивов и словарей, а затем использую writeToFile
для создания файла plist. И когда я хочу использовать этот plist, я теперь могу прочитать его одним звонком до arrayWithContentsOfFile
.
Это замечательно, спасибо за ваше время! – dan