Frage

Ich versuche, in zu lesen und ein XML-Dokument in einem iPhone app zu analysieren. Ich beginne das Parsen und dann die Überschreibung Methode verwenden:

   static void startElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI, 
                        int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes)

ich dann versuchen, die Attribute in eine Zeichenfolge zu konvertieren mit:

   NSString *str1 = [[NSString alloc] initWithCString:attributes encoding:NSUTF8StringEncoding];

Warum hat die Attribute Parameter haben zwei ** vor ihm. Und warum, wenn sie versuchen, die Daten zu extrahieren und wandelt es in eine Zeichenfolge mit dem obigen Code bekomme ich die Warnung:

Gabe des Arguments 1 von 'initWithCString: Codierung:' von inkompatiblen Zeigertyp

.
War es hilfreich?

Lösung

Die Dokumentation für libxml Element Rückruf starten dass der Zeiger besagt, ist mit einem Array, das 5-Werte für jedes Attribut (die Anzahl der Attribute zurückgegeben in nb_attributes) halten. Das bedeutet, dass jeder fünfte Wert im Array ist ein neues Attribut Element.

Die fünf Elemente für jedes Attribut sind:

  1. lokaler Name (der Name des Attributs)
  2. Präfix (der Namespace des Attributs)
  3. URI
  4. [Anfang] Wert (ein Zeiger auf den Anfang die xmlchar Zeichenfolge für den Wert)
  5. Ende [Wert] (ein Zeiger auf das Ende der xmlchar String für den Wert)

Sie müssen also durch das Array zu dem Schritt, jeden Wert aus den Elementen für das erste Attribut zu erhalten, verwenden Sie dann den Startwert Zeiger auf die xmlchar Zeichenfolge zu erhalten, die Länge = Ende - beginnen. Dann mit dem nächsten Attribute von vorn beginnen, bis Sie in nb_attributes lesen wert.

Wenn das macht den Kopf schmerzen dann empfehle ich Sie wechseln zu Apples NSXMLParser (Link kann Anmeldung erforderlich ist, oder diesen Link NSXMLParser ). In diesem Fall würden Sie die Attribute als NSDictionary bekommen. Um alle Attribute aus der es Sie Folgendes tun können:

for (NSString *attributeName in [attributeDict allKeys]) {
    NSString *attributeValue = [attributeDict objectForKey:attributeName];
    // do something here with attributeName and attributeValue
}

Wenn Sie den Zugriff auf die Website iPhone-Entwickler haben dann am Beispiel aussehen: SeismicXML .

Andere Tipps

Die Probe ist toll, bis auf zwei Dinge:

  • müssen Sie stoßen ‚i‘ um 5 nach jeder Schleife, da es 5 Elemente für jedes Attribut sind.
  • Ihr strlen () auf beide beginnen und Ende ist teuer; es ist einfacher, von einem Ende beginnen zu subtrahieren

for (int i = 0; i < nb_attributes*5; i += 5) 
{
    const char *attr = (const char *)attributes[i];
    const char *begin = (const char *)attributes[i + 3];
    const char *end = (const char *)attributes[i + 4];
    int vlen = end - begin;
    char val[vlen + 1];
    strncpy(val, begin, vlen);
    val[vlen] = '\0';
    NSLog(@"attribute %s = '%s'", attr, val);
}

Die akzeptierten Antworten Erklärung ist richtig, aber es ist hilfreich zu einig Beispiel-Code zu sehen. Hier ist nur ein Weg, um den Wert aus den Attributen zu extrahieren, zumindest funktioniert es, wenn ich es getestet. Ich bin weit davon entfernt, obwohl ein C-Guru zu sein.

for (int i = 0; i < nb_attributes; i += 5) {
    const char *attr = (const char *)attributes[i];
    const char *begin = (const char *)attributes[i + 3];
    const char *end = (const char *)attributes[i + 4];
    int vlen = strlen(begin) - strlen(end);
    char val[vlen + 1];
    strncpy(val, begin, vlen);
    val[vlen] = '\0';
    NSLog(@"attribute %s: %d = %s", attr, i, val);
}

NSXMLParser ist schön, aber von dem, was ich sagen kann, es lädt die gesamte XML vor der Verarbeitung. Mit Libxml kann es in Stücke zu einem Zeitpunkt lesen. Es ermöglicht eine größere Flexibilität, aber höhere Lernkurve.

Die '**' Notation bedeutet „Zeiger auf einen Zeiger.“ In C / C ++, ein „string“ wird durch eine Reihe von Zeichen dargestellt. Ein Array ist tatsächlich nur ein Zeiger unter der Decke, so dass eine Zeichenkette in C / C ++ kann tatsächlich entweder als „char []“ oder „char *“ deklariert werden. Die [] Notation kompiliert zu einem Array zu einem Zeiger nach unten.

Ein typisches Beispiel hierfür ist die typische "main" Funktion in C / C ++:

int main(int argc, char **argv)

Welche entspricht:

int main(int argc, char *argv[])

argv ist ein Array von char * "Strings" (die Befehlszeilenargumente für das Programm).

Ich kann nicht ein Beispiel zur Zeit zur Verfügung stellen, aber es sieht aus wie Sie über iterieren müssen Attribute der einzelnen Strings zuzugreifen. Zum Beispiel schreibt [0] würde die erste Attributzeichenfolge (eine xmlchar *) sein. Sie sollten jedes einzelne Attribut zu einem NSString konvertieren können.

const xmlChar **namespaces ist ein Array von CStrings (int nb_namespaces sagt Ihnen, wie viele). Wenn Sie jeden Namensraum als NSString möchten, können Sie so etwas wie das folgende tun könnte:

NSMutableArray *namespaces = [[NSMutableArray alloc] init];

int i;
for (i = 0; i < nb_namespaces; i++) {
    NSString *namespace = [[NSString alloc] initWithCString:attributes[i] encoding:NSUTF8StringEncoding];
    [namespaces addObject:namespace];
}

Die initWithCString Methode rechnet xmlChar *, die a ist Zeiger auf ein xmlchar (das erste Zeichen in einem CString).

xmlChar ** Mittel Zeiger auf einen Zeiger zu einem xmlchar (das erste Zeichen in dem ersten CString).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top