NSXMLParser - DTD nicht pruefen

  • NSXMLParser - DTD nicht pruefen

    moin,

    hab nun seit zwei wochen an nem x3d importer gebastelt, der den NSXMLParser benutzt. funktioniert alles einwandfrei, aber in den faellen, in denen ich mangelhaft netz habe (also hohe latenz oder garnicht), verliert man einen haufen zeit, bis die dtd online geprueft ist. also ich gehe davon aus, dass es die dtd ist, die da geprueft wird :)

    jetzt schlagt mich nicht, mim java sax konnte man das pruefen der dtd weglassen und einfach roh durch das dokument, das man da einliest, durchparsen.

    kann ich das mit NSXMLParser auch irgendwie erreichen?

    frank
  • Könntest du deine obligatorische Warnung vor NSXMLParser mal etwas konkreter gestalten. Sie taucht eigentlich in jedem Artikel in den dieser Begriff fällt auf, die Quelle dieses Traumas konnte ich allerdings noch nicht finden.

    Ich hab mit dem schon 2/3 der Amazon Datenbestände durchpflügt und das ging ohne Probleme?!?!
    Seminare, Artikel, Code. ObjectiveCeeds - alles für die Apfelzucht.
  • "09-Feb-2004 07:26 AM Alexander von Below:
    Dear Apple DTS,

    I am parsing an XML document using the new NSXMLParser.
    Surprisingly, the delegates receives the parser:foundCharacters message with strings like "\n\t", i.e. merely formatting characters of the XML file. The foundIgnorableWhitespace message of the delegate is never called.

    My workaround currently is to check the string for whitespace like this:

    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
    {
    ...
    NSString * tempStr = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    if ([tempStr isEqualToString:@""])
    NSLog (@"Ignorable Whitespace was sent to foundCharacters!\n");
    else
    [currentString appendString:string];
    return;
    }"

    Geht das bei Dir?

    Der Bug steht bei mir noch als "Open"

    Alex
    The only thing that really worried me was the ether.
  • Nö, ich krieg die Zeichen auch.

    Hab ich ein Problem damit? Nein!

    Characters interessieren mich nur zwischen einem Start und einem End Element. Die Implementierung in diesem Workarround würde ich auch mal als ganz schlecht bezeichnen, denn wenn die Daten zwischen zwei Tags "ignorable Whitespaces" enthalten kann ich die nicht einfach blind rausschneiden.

    In den Griff bekomme ich das z.B. wenn ich beim Start Element entscheide ob dieses Element Characters enhält und dann einfach nen BOOL AcceptCharacters auf YES setze und beim Endelement wieder auf NO.

    Ich sehe darin auch keinen Bug, der Parser scannt durch, das was einen Event auslöst wird geschickt und der Rest einfach als Characters.

    Gruß
    Seminare, Artikel, Code. ObjectiveCeeds - alles für die Apfelzucht.
  • Hier ist meine Demo. Schau Dir das testfile.xml im Editor an, und setz dann einen Breakpoint auf den foundCharacters Delegate

    Da kommt als erstes ein String "\n\t", das ist doch Quatsch, oder hab ich was nicht verstanden?

    Alex
    The only thing that really worried me was the ether.
  • Beispiel:

    XML-Quellcode

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE addresses SYSTEM "addresses.dtd">
    3. <addresses owner="swilson">
    4. <person>
    5. <lastName>Doe</lastName>
    6. <firstName>John</firstName>
    7. <phone location="mobile">(201) 345-6789</phone>
    8. <email>jdoe@foo.com</email>
    9. <address>
    10. <street>100 Main Street</street>
    11. <city>Somewhere</city>
    12. <state>New Jersey</state>
    13. <zip>07670</zip>
    14. </address>
    15. </person>
    16. <!-- more person elements go here -->
    17. </addresses>
    Alles anzeigen


    Das ist der XML Schnipsel und das sind die Events:

    Quellcode

    1. 2007-11-28 15:24:31.811 XMLExample[1588:10b] Start
    2. 2007-11-28 15:24:31.812 XMLExample[1588:10b] FoundElement addresses
    3. 2007-11-28 15:24:31.812 XMLExample[1588:10b] FoundCharacters
    4. 2007-11-28 15:24:31.813 XMLExample[1588:10b] FoundElement person
    5. 2007-11-28 15:24:31.813 XMLExample[1588:10b] FoundCharacters
    6. 2007-11-28 15:24:31.813 XMLExample[1588:10b] FoundElement lastName
    7. 2007-11-28 15:24:31.814 XMLExample[1588:10b] FoundCharacters Doe
    8. 2007-11-28 15:24:31.814 XMLExample[1588:10b] EndOfElement lastName
    9. 2007-11-28 15:24:31.815 XMLExample[1588:10b] FoundCharacters
    10. 2007-11-28 15:24:31.815 XMLExample[1588:10b] FoundElement firstName
    11. 2007-11-28 15:24:31.815 XMLExample[1588:10b] FoundCharacters John
    12. 2007-11-28 15:24:31.816 XMLExample[1588:10b] EndOfElement firstName
    13. 2007-11-28 15:24:31.816 XMLExample[1588:10b] FoundCharacters
    14. 2007-11-28 15:24:31.816 XMLExample[1588:10b] FoundElement phone
    15. 2007-11-28 15:24:31.817 XMLExample[1588:10b] FoundCharacters (201) 345-6789
    16. 2007-11-28 15:24:31.817 XMLExample[1588:10b] EndOfElement phone
    17. 2007-11-28 15:24:31.818 XMLExample[1588:10b] FoundCharacters
    18. 2007-11-28 15:24:31.818 XMLExample[1588:10b] FoundElement email
    19. 2007-11-28 15:24:31.818 XMLExample[1588:10b] FoundCharacters jdoe@foo.com
    20. 2007-11-28 15:24:31.819 XMLExample[1588:10b] EndOfElement email
    21. 2007-11-28 15:24:31.819 XMLExample[1588:10b] FoundCharacters
    22. 2007-11-28 15:24:31.822 XMLExample[1588:10b] FoundElement address
    23. 2007-11-28 15:24:31.823 XMLExample[1588:10b] FoundCharacters
    24. 2007-11-28 15:24:31.823 XMLExample[1588:10b] FoundElement street
    25. 2007-11-28 15:24:31.824 XMLExample[1588:10b] FoundCharacters 100 Main Street
    26. 2007-11-28 15:24:31.824 XMLExample[1588:10b] EndOfElement street
    27. 2007-11-28 15:24:31.825 XMLExample[1588:10b] FoundCharacters
    28. 2007-11-28 15:24:31.825 XMLExample[1588:10b] FoundElement city
    29. 2007-11-28 15:24:31.826 XMLExample[1588:10b] FoundCharacters Somewhere
    30. 2007-11-28 15:24:31.826 XMLExample[1588:10b] EndOfElement city
    31. 2007-11-28 15:24:31.827 XMLExample[1588:10b] FoundCharacters
    32. 2007-11-28 15:24:31.827 XMLExample[1588:10b] FoundElement state
    33. 2007-11-28 15:24:31.828 XMLExample[1588:10b] FoundCharacters New Jersey
    34. 2007-11-28 15:24:31.828 XMLExample[1588:10b] EndOfElement state
    35. 2007-11-28 15:24:31.828 XMLExample[1588:10b] FoundCharacters
    36. 2007-11-28 15:24:31.829 XMLExample[1588:10b] FoundElement zip
    37. 2007-11-28 15:24:31.829 XMLExample[1588:10b] FoundCharacters 07670
    38. 2007-11-28 15:24:31.830 XMLExample[1588:10b] EndOfElement zip
    39. 2007-11-28 15:24:31.830 XMLExample[1588:10b] FoundCharacters
    40. 2007-11-28 15:24:31.830 XMLExample[1588:10b] EndOfElement address
    41. 2007-11-28 15:24:31.831 XMLExample[1588:10b] FoundCharacters
    42. 2007-11-28 15:24:31.831 XMLExample[1588:10b] EndOfElement person
    43. 2007-11-28 15:24:31.832 XMLExample[1588:10b] FoundCharacters
    44. 2007-11-28 15:24:31.833 XMLExample[1588:10b] FoundCharacters
    45. 2007-11-28 15:24:31.834 XMLExample[1588:10b] EndOfElement addresses
    46. 2007-11-28 15:24:31.834 XMLExample[1588:10b] End
    Alles anzeigen


    Fangen wir mal an,

    found Element Adresses, das wird ein Array ;

    found Characters -> die Zeilenumbrüche etc. des Dokuments -> interessiert nicht, da ein Array keine Characters aufnimmt, sondern auf "Unterelemente" wartet -> klarer Fall, wird ignoriert;

    found Element Person, das wird ein Dictionary;

    found Characters -> die Zeilenumbrüche etc. des Dokuments -> interessiert nicht, da ein Dictionary keine Characters aufnimmt, sondern auf "Unterelemente" wartet -> klarer Fall, wird ignoriert;

    found Element lastName -> wird ein String;
    found Characters -> wir warten auf nen String -> stimmt!;
    EndOfElement lastName -> string fertig d.h. unser "aktives Element" ist wieder Person;

    found Characters -> die Zeilenumbrüche etc. des Dokuments -> interessiert nicht, da ein Dictionary keine Characters aufnimmt, sondern auf "Unterelemente" wartet -> klarer Fall, wird ignoriert;

    FoundElement firstName -> wird ein String;
    found Characters -> wir warten auf nen String -> stimmt!;
    EndOfElement firsName -> string fertig d.h. unser "aktives Element" ist wieder Person;

    found Characters -> die Zeilenumbrüche etc. des Dokuments -> interessiert nicht, da ein Dictionary keine Characters aufnimmt, sondern auf "Unterelemente" wartet -> klarer Fall, wird ignoriert;

    usw. usw.

    -------------------------------------------------

    Wenn ich das mit nem Stapel verarbeite wird das ganz einfach.

    Ich bekomme ein Startelement "Adresses" und lege ein NSMutableArray auf den Stapel.

    Ich bekomme Characters -> das letzt Objekt auf dem Stapel ist das Array -> nix mit characters

    Ich bekomme ein Startelement "Person" und lege ein NSMutableDictionary auf den Stapel.

    Ich bekomme Characters -> das letzt Objekt auf dem Stapel ist das Dictionary -> nix mit characters

    Ich bekomme ein Startelement "lastName" und lege ein NSMutableString auf den Stapel.

    Ich bekomme Characters -> das letzt Objekt auf dem Stapel ist der String -> rein damit

    Ich bekomme ein Endelement "lastName" und nehme das oberste Objekt vom Stapel

    Ich bekomme Characters -> das letzt Objekt auf dem Stapel ist das Dictionary -> nix mit characters

    usw. usw.
    Seminare, Artikel, Code. ObjectiveCeeds - alles für die Apfelzucht.
  • Original von kressevadder
    Das klingt logisch ... seit drei Jahren hat Apple da aber zu meinem Verständnisproblem nichts gesagt.

    Na gut, daß du mal mit nem Sozialpädagogen darüber gesprochen hast ;)


    "found Characters -> die Zeilenumbrüche etc. des Dokuments -> interessiert nicht, da ein Dictionary keine Characters aufnimmt, sondern auf "Unterelemente" wartet -> klarer Fall, wird ignoriert;"

    Das finde ich halt eben keinen so "klaren Fall". Diese Dinge sind ignorable Whitespace, finde ich- Wozu ist die Delegate Methode sonst da?

    Alex
    The only thing that really worried me was the ether.
  • Mhh,

    ich seh das ehr so, das NSXMLParser einfach eine Art NSScanner ist, der auf die XML Elemente reagiert, alles was nicht zu einem Element gehört wird stupide als "Rest" rausgehauen.

    Kann der Parser das überhaupt entscheiden? Der hat ja keine Ahnung ob "Persons" nun ein Array ist oder ein String bei dem das interessant ist. OK, dafür gibts die DTD, da könnte sich der Parser mal schlau machen was da kommt, aber ich denke einfach mal, NSXMLParser arbeitet nicht auf so nen hohen Level.
    Seminare, Artikel, Code. ObjectiveCeeds - alles für die Apfelzucht.
  • Original von below
    Bitte nicht NSXMLParser!

    Nimm CFXMLParser oder NSXML bzw. NSXMLDocument!
    Soweit ich weiss ist NSXMLDocument einfach auf NSXMLParser aufgesetzt und benutzt ihn intern. Zumindest habe ich den Hinweis bei validateAndReturnError so verstanden.

    Also kann der nicht wirklich so schlecht sein. Ich habe damit bisher auch keine Probleme gehabt.

    -- hns
  • Original von below
    Das finde ich halt eben keinen so "klaren Fall". Diese Dinge sind ignorable Whitespace, finde ich- Wozu ist die Delegate Methode sonst da?

    XHTML ist ja auch XML. Und da ist erlaubt:

    Quellcode

    1. <p> x <b> x </b> x </p>
    Keines von den Spaces ist aus Parser-Sicht ignorable.

    Genaueres zum Ignorable Whitespace findet man unter: cafeconleche.org/books/xmljava/chapters/ch06s10.html

    Dort ist es so mehr oder weniger als eine optionale Parser-Eigenschaft definiert bzw. wird über die DTD gesteuert.

    -- hns
  • das ist nun eigentlich peinlich..

    hab geschaut, ob foundExternalEntityDeclaration angeschubbst wird oder nicht. es wird geschubbst und resolved wie wild.

    daraufhin dacht ich, hmmmm, hat der kressevadder doch den richtigen hinweis gehabt und sollt ich nicht mal setShouldResolveExternalEntities auf NO setzen.. was hab ich gemerkt.. aus irgendeinem grund hab ich dort in der initialisierung der parsers schon YES eingetragen.

    jetzt klappts auch mim schnellen parsen.

    sorry for the noise.. :sick: