XMLStreamReader для Objective C iPhone? - PullRequest
4 голосов
/ 13 января 2011

Я использую XMLWriter для генерации XML. Теперь я хочу прочитать этот XML-файл с помощью некоторой библиотеки / фреймворка Reader. Есть ли для этого дополнительные рамки / библиотеки?

В настоящее время я хочу использовать библиотеку TouchXML для ее чтения, но она не работает ожидаемым образом, поскольку не поддерживает потоковое чтение.

Я хочу сделать что-то вроде:

XmlReader pReader = XmlTextReader.Create(pPath);

    while (pReader.Read()){

        switch (pReader.LocalName){
            case EXPEL_DEVICES:
            {
                //if ((pImportFlags & (int)ExportClass.Devices) != 0)
                //{
                for (pReader.ReadToFollowing(LOCAL_NAME, NAMESPACE_EXPORT);
                     !pReader.EOF && pReader.LocalName == @"NAME"; )
                {
                    if (!pReader.ReadToFollowing(DEVICE_ID, NAMESPACE_EXPORT))
                        throw new AException(DEVICE_ID);
                    NSString *value = pReader.ReadElementContentAsString();
                }
            }
                break;
        }
    }

Ответы [ 3 ]

1 голос
/ 28 января 2011

Потеряв собственную репутацию на 50, я, наконец, использовал libxml2 и сделал свой класс XMLStreamReader следующим образом, я хотел бы найти это раньше: P.Обратите внимание, что для использования этого нам нужно включить libxml2.dylib в наши фреймворки и в настройках сборки добавить -lxml2 в другие флаги компоновщика и в пути поиска заголовка добавить /usr/include/libxml2

Заголовочный файл:

#import <Foundation/Foundation.h>
#import <libxml/xmlreader.h>

@interface XMLStreamReader : NSObject {
    xmlTextReaderPtr xmlReader;
}

@property (nonatomic, readonly, assign) BOOL eof;
@property (nonatomic, readonly, retain) NSString *localName;
@property (nonatomic, readonly, assign) xmlElementType nodeType;
@property (nonatomic, readonly, assign) BOOL read;
@property (nonatomic, readonly, assign) BOOL readElementContentAsBoolean;
@property (nonatomic, readonly, retain) NSString *readElementContentAsString;

- (void) close;
- (id) getAttribute:(NSString *) paramName;
- (id) initWithPath:(NSString *) path;
@end

Файл реализации:

#import "XMLStreamReader.h"

@implementation XMLStreamReader

@dynamic eof;
@dynamic localName;
@dynamic nodeType;
@dynamic read;
@dynamic readElementContentAsBoolean;
@dynamic readElementContentAsString;

- (void) dealloc{
    xmlFreeTextReader(xmlReader);
    [super dealloc];
}

/**
 * xmlTextReaderClose:
 * @reader:  the xmlTextReaderPtr used
 *
 * This method releases any resources allocated by the current instance
 * changes the state to Closed and close any underlying input.
 *
 * Returns 0 or -1 in case of error
 */
- (void) close{
    xmlTextReaderClose(xmlReader);
}

/**
 * @reader:  the xmlTextReaderPtr used
 * @name: the qualified name of the attribute.
 *
 * Provides the value of the attribute with the specified qualified name.
 *
 * Returns a string containing the value of the specified attribute, or NULL
 *    in case of error. The string must be deallocated by the caller.
 */
- (id) getAttribute:(NSString *) paramName{
    xmlChar *attribute = xmlTextReaderGetAttribute(xmlReader, (xmlChar *)[paramName UTF8String]);

    if(attribute != NULL){
        NSString *rtString = [NSString stringWithUTF8String:(const char *)attribute];
        free(attribute);
        return rtString;
    }
    return NULL;
}

/**
 * Checks if, the reader has reached to the end of file
 * 'EOF' is not used as it is already defined in stdio.h
 * as '#define  EOF (-1)'
 */
- (BOOL) eof{
    return xmlTextReaderReadState(xmlReader) == XML_TEXTREADER_MODE_EOF;
}

/**
 * Initializing the xml stream reader with some uri
 * or local path.
 */
- (id) initWithPath:(NSString *) path{
    if(self = [super init]){
        xmlReader = xmlNewTextReaderFilename([path UTF8String]);
        if(xmlReader == NULL)
            return nil;
    }
    return self;
}

/**
 * @reader:  the xmlTextReaderPtr used
 *
 * The local name of the node.
 *
 * Returns the local name or NULL if not available,
 *   if non NULL it need to be freed by the caller.
 */
- (NSString *) localName{
    xmlChar *lclName = xmlTextReaderLocalName(xmlReader);

    if(lclName != NULL){
        NSString *rtString = [NSString stringWithUTF8String:(const char *)lclName];
        free(lclName);
        return rtString;
    }
    return NULL;
}

- (xmlElementType) nodeType{
    return xmlTextReaderNodeType(xmlReader);
}

/**
 * @reader:  the xmlTextReaderPtr used
 *
 *  Moves the position of the current instance to the next node in
 *  the stream, exposing its properties.
 *
 *  Returns 1 if the node was read successfully, 0 if there is no more
 *          nodes to read, or -1 in case of error
 */
- (BOOL) read{
    return xmlTextReaderRead(xmlReader);
}

/**
 * @reader:  the xmlTextReaderPtr used
 *
 * Reads the contents of an element or a text node as a Boolean.
 *
 * Returns a string containing the contents of the Element or Text node,
 *         or NULL if the reader is positioned on any other type of node.
 *         The string must be deallocated by the caller.
 */
- (void) readElementContentAsBoolean{
    return [[self readElementContentAsString] boolValue];
}

/**
 * @reader:  the xmlTextReaderPtr used
 *
 * Reads the contents of an element or a text node as a string.
 *
 * Returns a string containing the contents of the Element or Text node,
 *         or NULL if the reader is positioned on any other type of node.
 *         The string must be deallocated by the caller.
 */
- (NSString *) readElementContentAsString{
    xmlChar *content = xmlTextReaderReadString(xmlReader);

    if(content != NULL){
        NSString *rtString = [NSString stringWithUTF8String:(const char *)content];
        free(content);
        return rtString;
    }
    return NULL;
}

/**
 * @reader:  the xmlTextReaderPtr used
 * @localName:  the local name of the attribute.
 * @namespaceURI:  the namespace URI of the attribute.
 *
 * Moves the position of the current instance to the attribute with the
 * specified local name and namespace URI.
 *
 * Returns 1 in case of success, -1 in case of error, 0 if not found
 */
- (int) readToFollowing:(NSString *) localname namespace:(NSString *) namespaceURI{
    return xmlTextReaderMoveToAttributeNs(xmlReader, (xmlChar *)[localname UTF8String], (xmlChar *)[namespaceURI UTF8String]);
}

@end
0 голосов
/ 27 января 2011

Вы можете перейти прямо к источнику, используя libxml2 и их XmlReader API. Он основан на API-интерфейсе XmlReader в C #, на который вы, похоже, ссылались выше, но в C.

Я понимаю, что это не цель-c, но вы могли бы легко обернуть функциональность в класс, к которому обращается остальная часть вашего проекта.

0 голосов
/ 13 января 2011

NSXMLParser входит в состав Foundation, который может удовлетворить ваши потребности.

...