xpaths и xml итерация - PullRequest
       3

xpaths и xml итерация

0 голосов
/ 22 февраля 2012

У меня есть xml вроде этого:

    <root>
   ...
    <images xmlns:a="http://.../Arrays">
        <a:string>http://images...233/Detail.jpg</a:string>
        <a:string>http://images....233/Detail2.jpg</a:string>
    </images>
   ...
   <images xmlns:a="http://.../Arrays">
        <a:string>http://images...233/Detail3.jpg</a:string>
        <a:string>http://images....233/Detail4.jpg</a:string>
        <a:string>http://images....233/Detail5.jpg</a:string>
    </images>
....
<images xmlns:a="http://.../Arrays">
        <a:string>http://images...233/Detail6.jpg</a:string>
        <a:string>http://images....233/Detail7.jpg</a:string>
    </images>
   ....
<root>

Как я могу повторить, чтобы поместить все мои изображения в NSArray?

Ответы [ 2 ]

0 голосов
/ 22 февраля 2012

Чтобы сделать это на устройстве iOS, предпочтительно использовать стороннюю библиотеку C, которая реализует оценку XPath для вас, в отличие от встроенной поддержки XML, предоставляемой для iOS. Лучше всего использовать libxslt, но поскольку загружаемая версия libxslt представлена ​​в виде динамической библиотеки, ее нельзя использовать непосредственно на iOS. Вместо этого вам захочется скачать исходный код для libxslt и встроить его прямо в ваше приложение. См. этот пост для получения дополнительной информации о том, как заставить libxslt работать на iOS.

Когда у вас есть libxslt, работающий в вашем проекте, вы можете использовать код C для анализа XML и оценки произвольных выражений XPath, таких как "/ / / text ()", как это было предложено @Dmitre Novatchev , Есть много вариантов того, как вы можете это сделать, но что-то вроде этого дает вам пример:

CFArrayRef findImages(CFStringRef filename) {

    xmlInitParser();
    LIBXML_TEST_VERSION

    // Parse XML template document into DOM tree
    CFIndex filenameLength = CFStringGetLength(filePath);
    char *fileNameCString = (char *) calloc(filenameLength + 1, sizeof(char));
    CFStringGetCString(filePath, fileNameCString, filenameLength + 1, kCFStringEncodingUTF8);

    xmlDocPtr doc = xmlReadFile(fileNameCString, NULL, 0);
    if (doc == NULL) 
    {
        // Error - File not readable
        free(fileNameCString);
        return nil;
    }
    else
    {
        free(fileNameCString);
        xmlCleanupParser();
    }

    /* Create xpath evaluation context */
    xmlXPathContextPtr xpathCtx = xmlXPathNewContext(doc);
    if(xpathCtx == NULL) 
    {
        // Error - Failed to create Xpath context
        return NULL;
    }


    /* Evaluate xpath expression */
    char *xpathCString = "/*/*/text()";
    xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(BAD_CAST xpathCString, xpathCtx);
    if(xpathObj == NULL) 
    {
        // Error - Failed to evaluate XPath
        xmlXPathFreeContext(xpathCtx); 
        return NULL;
    }
    xmlNodeSetPtr resultNodes = xpathObj->nodesetval;


    // You'll want to double-check the following part: I don't have sample code for
    // this so I can't be certain this is 100% correct, but it gets the idea across!

    CFMutableArrayRef result = CFArrayCreate(kCFAllocatorDefault, 0, NULL);
    for (int i = 0; i < resultNodes->nodeNr; i++) {
        char *imageCString = xmlNodeGetContent(resultNodes->nodeTab[i]);
        CFStringRef imageString = CFStringCreateWithCString(kCFAllocatorDefault, imageCString, kCFStringEncodingUTF8);
        CFArrayAppendValue(result, imageString);
    }

    return result;
}

Я собрал этот пример кода на основе некоторого рабочего примера кода, который был у меня для оценки выражения XPath, но конечная часть, где я собираю его в массив, не в моей голове: он может работать не совсем правильно !

Обратите внимание, что эта функция принимает CFString для имени файла XML-файла и возвращает CFArray для результата. Эти типы являются «бесплатными мостовыми» с типами Objective-C NSString и NSArray. Это означает, что вы можете вызывать их из Objective-C с «обычными» типами, которые вы привыкли использовать, и они будут правильно поняты в коде C, который я предоставил.

0 голосов
/ 22 февраля 2012

Как я могу повторить, чтобы поместить все мои изображения в NSArray?

Я не знаю, что вы подразумеваете под NSArray.

Обычно движок XPath предоставляет метод, подобный SelectNodes(string XpathExpression), возможно, с перегрузками для NamespaceManager аргумента объекта.

И этот метод обычно возвращает объект XmlNodelist, который содержит все результаты и позволяет перебирать их.

Одно выражение XPath, которое выбирает все текстовые узлы, которые содержат изображения в предоставленном документе XML :

<images xmlns:a="http://.../Arrays">
    <a:string>http://images...233/Detail.jpg</a:string>
    <a:string>http://images....233/Detail2.jpg</a:string>
</images>

это

/*/*/text()

При этом выбирается любой текстовый узел, родительский элемент которого является дочерним по отношению к верхнему элементу в документе XML - в этом случае такими узлами являются в точности два текстовых узла со строковым значением соответственно:

"http://images...233/Detail.jpg"

и

"http://images....233/Detail2.jpg".

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...