Nested XML -> CoreData

  • I'm parsing a large XML file using NSXMLParser (OS X) and part of the
    nested structure is similar to this:

    <Person>
    ...
    ...
    <PhoneNumbers>
    <PhoneNumber>
      <PhoneNumberType>Home</PhoneNumberType>
      <PhoneNumberValue>123-555-1234</PhoneNumberValue>
    </PhoneNumber>
    <PhoneNumber>
      <PhoneNumberType>Work</PhoneNumberType>
      <PhoneNumberValue>345-555-6612</PhoneNumberValue>
    </PhoneNumber>
    <PhoneNumber>
      <PhoneNumberType>Mobile</PhoneNumberType>
      <PhoneNumberValue>222-555-8901</PhoneNumberValue>
    </PhoneNumber>
    </PhoneNumbers>
    ...
    ...
    </Person>

    In advance I don't know how many phonenumbers there will be, there could be
    none, or more than three, and they also may have a different
    <PhoneNumberType>  (eg 'Second Home'). The obvious thing to do I guess, is
    just everytime the parser reaches <PhoneNumbers>, I create an array, and
    every time the parser reaches <PhoneNumber> I create a dictionary, fill it
    with the type and number and add that to the array when </PhoneNumber> is
    reached.

    However, the data read with the parser needs to end up in my Core Data
    model. Obviously I already created a Person entity, but how do I add the
    phone numbers to it? Create a PhoneNumber entity with two attributes? Or
    stuff the PhoneNumbers array in an NSData object, and make that an
    attribute of the Person entity, and pull out the data when needed? I see
    the advantage of the former, in case I want to find out which Persons share
    a PhoneNumber (or Address, Car, etc).

    I guess my question is, should I make my CoreData model as nested as my XML
    file is, with lots of small entities?

    Furthermore, converting an XML file into strings, arrays and dictionaries,
    and then converting it back to Entities which are stored in an XML
    structure in the store seems over complicated to me. Any thoughts on that?

    - Koen.
  • On May 15, 2012, at 7:29 AM, Koen van der Drift <koenvanderdrift...> wrote:

    > However, the data read with the parser needs to end up in my Core Data
    > model. Obviously I already created a Person entity, but how do I add the
    > phone numbers to it? Create a PhoneNumber entity with two attributes?

    That would be a reasonable approach.

    > Or
    > stuff the PhoneNumbers array in an NSData object, and make that an
    > attribute of the Person entity, and pull out the data when needed?

    That would be working at cross-purposes to the framework.

    > I see
    > the advantage of the former, in case I want to find out which Persons share
    > a PhoneNumber (or Address, Car, etc).
    >
    > I guess my question is, should I make my CoreData model as nested as my XML
    > file is, with lots of small entities?

    That’s definitely not unreasonable. You may not partition them exactly the same though. For example, your XML may have a unique label for each phone number. In your data model, however, you may have *three* entities instead of two:

      Person
      PhoneNumber
      PhoneNumberLabel

    And then you can have each PhoneNumber labeled “Home” in the XML may wind up pointing to the same PhoneNumberLabel instance, normalizing your data.

    You might even use hierarchy in your model, if you have other things that are labeled.

    For example:

      Person
      Address
      PhoneNumber
      Label
        PhoneNumberLabel
        AddressLabel

    where:

      entity Label {
        string name;
      };
      entity PhoneNumberLabel : Label {
        to-many relationship phoneNumbers
            to entity PhoneNumber
            with inverse phoneNumberLabel;
      };
      entity AddressLabel : Label {
        to-many relationship addresses
            to entity Address
            with inverse label;
      };

    This way your concept of a “label” is used once per labeled entity. You will have duplication between the Home phone number label and the Home address label, though this (usually) isn’t something that’s an issue; you can address this too, if you want, via further normalization.

    > Furthermore, converting an XML file into strings, arrays and dictionaries,
    > and then converting it back to Entities which are stored in an XML
    > structure in the store seems over complicated to me. Any thoughts on that?

    Core Data provides management of object graphs over an abstraction of storage.

    It’s up to the developer to choose the specific persistent store type that fits their application, though in most cases this will very likely be the SQLite persistent store type, not the XML persistent store type. That allows you to avoid bringing your entire object graph into memory at once; instead, only the parts of it that you’re accessing are read.

      -- Chris
  • Thanks for the feedback, very helpful. I will definitely swich to an
    sqlstore, right now I am using xml for debugging purposes. I will also
    create entities for each node.

    - Koen.

    On Tue, May 15, 2012 at 7:49 PM, Chris Hanson <cmh...> wrote:

    > On May 15, 2012, at 7:29 AM, Koen van der Drift <koenvanderdrift...>
    > wrote:
    >
    >> However, the data read with the parser needs to end up in my Core Data
    >> model. Obviously I already created a Person entity, but how do I add the
    >> phone numbers to it? Create a PhoneNumber entity with two attributes?
    >
    > That would be a reasonable approach.
    >
    >> Or
    >> stuff the PhoneNumbers array in an NSData object, and make that an
    >> attribute of the Person entity, and pull out the data when needed?
    >
    > That would be working at cross-purposes to the framework.
    >
    >> I see
    >> the advantage of the former, in case I want to find out which Persons
    > share
    >> a PhoneNumber (or Address, Car, etc).
    >>
    >> I guess my question is, should I make my CoreData model as nested as my
    > XML
    >> file is, with lots of small entities?
    >
    > That’s definitely not unreasonable. You may not partition them exactly the
    > same though. For example, your XML may have a unique label for each phone
    > number. In your data model, however, you may have *three* entities instead
    > of two:
    >
    > Person
    > PhoneNumber
    > PhoneNumberLabel
    >
    > And then you can have each PhoneNumber labeled “Home” in the XML may wind
    > up pointing to the same PhoneNumberLabel instance, normalizing your data.
    >
    > You might even use hierarchy in your model, if you have other things that
    > are labeled.
    >
    > For example:
    >
    > Person
    > Address
    > PhoneNumber
    > Label
    > PhoneNumberLabel
    > AddressLabel
    >
    > where:
    >
    > entity Label {
    > string name;
    > };
    > entity PhoneNumberLabel : Label {
    > to-many relationship phoneNumbers
    > to entity PhoneNumber
    > with inverse phoneNumberLabel;
    > };
    > entity AddressLabel : Label {
    > to-many relationship addresses
    > to entity Address
    > with inverse label;
    > };
    >
    > This way your concept of a “label” is used once per labeled entity. You
    > will have duplication between the Home phone number label and the Home
    > address label, though this (usually) isn’t something that’s an issue; you
    > can address this too, if you want, via further normalization.
    >
    >> Furthermore, converting an XML file into strings, arrays and
    > dictionaries,
    >> and then converting it back to Entities which are stored in an XML
    >> structure in the store seems over complicated to me. Any thoughts on
    > that?
    >
    > Core Data provides management of object graphs over an abstraction of
    > storage.
    >
    > It’s up to the developer to choose the specific persistent store type that
    > fits their application, though in most cases this will very likely be the
    > SQLite persistent store type, not the XML persistent store type. That
    > allows you to avoid bringing your entire object graph into memory at once;
    > instead, only the parts of it that you’re accessing are read.
    >
    > -- Chris
    >
    >
  • On 2012 May 16, at 09:34, Koen van der Drift wrote:

    > I will definitely swich to an sqlstore, right now I am using xml for debugging purposes.

    You should switch to the SQLite store sooner rather than later.

    Although I have seen it implied that it is appropriate to develop with XML and "flip the switch" to SQLite the day before you ship, in a project of any significant complexity you'll be bitten by one or more of Core Data's SQLite gotchas.

    There are GUI tools such as SQLiteManager which, although cranky, make reading SQLite files for debugging no more painful than reading XML, maybe even less painful since you can execute queries.  After you learn your way around, the free command-line tool sqlite3 from sqlite.org is also useful.

    Entities become tables, properties become columns.  Both names are made uppercase and prefixed with "Z" or "Z_".  Not at all difficult.
previous month may 2012 next month
MTWTFSS
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Go to today