NSXMLParser 从 XML 标签中检索错误数据

2023-12-01

我正在读取带有某些字段的 xml,例如:

<url>http://myurl.com/noticias/redirect.html?document=xx222&usuario=44yyy&url=http%3A%2F%2Fwww.environmental-expert.com%2FresultEachPressRelease.aspx%3Fcid%3D23745%26codi%3D234441%26lr%3D1</url>

<title>The world water report – supplies falling, Tensions Rising</title>

输出是:

2011-04-28 17:08:02.191 MyProject[12093:207] doc found

2011-04-28 17:08:02.192 MyProject[12093:207] url=http%3A%2F%2Fwww.environmental-expert.com%2FresultEachPressRelease.aspx%3Fcid%3D23745%26codi%3D234441%26lr%3D1

2011-04-28 17:08:02.193 MyProject[12093:207] – supplies falling, Tensions Rising

这与 xml 文件中的数据不匹配。

我的解析器有以下方法:

// Start of element
- (void)parser:(NSXMLParser *)parser
                didStartElement:(NSString *)elementName
                namespaceURI:(NSString *)namespaceURI
                qualifiedName:(NSString *)qName
                attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"document"]){
        NSLog(@"doc found");

    }
}

// Found Character
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSMutableString *)string
{
    currentNodeContent = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}


// End Element
- (void) parser:(NSXMLParser *)parser
                didEndElement:(NSString *)elementName
                namespaceURI:(NSString *)namespaceURI
                qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"url"]){

        NSLog(@"%@", currentNodeContent);

    }
    if ([elementName isEqualToString:@"title"]){

        NSLog(@"%@", currentNodeContent);

    }



    if ([elementName isEqualToString:@"document"]){
        [currentNodeContent release];
        currentNodeContent = nil;
    }

}

它可以与函数foundCharacters有关吗?

在此先感谢您的帮助!


发现一个字段的字符可以被调用多次! 您应该创建一个临时 NSMutableString 并附加 findcaracters 结果!

// Start of element
- (void)parser:(NSXMLParser *)parser
didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName
    attributes:(NSDictionary *)attributeDict
{
    if ([elementName isEqualToString:@"document"]){
        NSLog(@"doc found");

        if (temp != nil) {
            [temp release];
        }

        // Alloc temp string
        currentNodeContent = [[NSMutableString alloc] init];


    }
}

// Found Character
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSMutableString *)string
{
    if (currentNodeContent != nil) {
        [currentNodeContent appendString:[string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    }
}


// End Element
- (void) parser:(NSXMLParser *)parser
  didEndElement:(NSString *)elementName
   namespaceURI:(NSString *)namespaceURI
  qualifiedName:(NSString *)qName
{
    if ([elementName isEqualToString:@"url"]){

        NSLog(@"%@", currentNodeContent);

    }
    if ([elementName isEqualToString:@"title"]){

        NSLog(@"%@", currentNodeContent);

    }



    if ([elementName isEqualToString:@"document"]){
        [currentNodeContent release];
        currentNodeContent = nil;
    }

    // Release temp string
    [currentNodeContent release];
    currentNodeContent = nil;


}

请务必将 currentNodeContent 声明为 NSMutableString 而不是 NSString !

这是我在项目中使用的 xml 解析器代码:

//
//  XMLParser.h
//

#import <Foundation/Foundation.h>
#import "XMLNode.h"

#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_3_2
@interface XMLParser : NSObject <NSXMLParserDelegate> {
#else
@interface XMLParser : NSObject {
#endif
    XMLNode *rootElement;
    XMLNode *tempElement;
    NSMutableString *temp;
    NSMutableArray *elements;
}

- (NSObject *)parseData:(NSData *)data;

// NSXMLParser delegate implementation
- (void)parserDidStartDocument:(NSXMLParser *)parser;
- (void)parserDidEndDocument:(NSXMLParser *)parser;
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict;
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;

@end

-

//
//  XMLParser.m
//

#import "XMLParser.h"


@implementation XMLParser

- (NSObject *)parseData:(NSData *)data
{
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    [parser setDelegate:self];
    [parser setShouldResolveExternalEntities:YES];

    if (![parser parse]) {
        if ([[parser parserError] code] == NSXMLParserUnknownEncodingError) {
            // If encoding is "us-ascii" replace encoding with something known (as NSXMLParser is not supporting this encoding)
            NSString *oldString = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
            NSString *newEncodingString = [oldString stringByReplacingOccurrencesOfString:@"encoding=\"us-ascii\"" withString:@"encoding=\"iso-8859-1\"" options:0 range:NSMakeRange(0,100)];
            newEncodingString = [newEncodingString stringByReplacingOccurrencesOfString:@"encoding=\"windows-1251\"" withString:@"encoding=\"iso-8859-1\"" options:0 range:NSMakeRange(0,100)];

            [oldString release];
            NSData *nameData = [newEncodingString dataUsingEncoding:NSASCIIStringEncoding];
            NSXMLParser *parser2 = [[NSXMLParser alloc] initWithData:nameData];
            [parser2 setDelegate:self];
            [parser2 setShouldResolveExternalEntities:YES];
            if (![parser2 parse]) {
                DLog(@"parseXML error : %@",[[parser2 parserError] localizedDescription]);
            }
            [parser2 release];

        } else {
            DLog(@"parseXML error : %@",[[parser parserError] localizedDescription]);
        }

    }
    [parser release];

    return rootElement;
}


- (void)dealloc
{
    if (tempElement != nil) {
        [tempElement release];
    } 
    if (rootElement != nil) {
        [rootElement release];
    }
    if (temp != nil) {
        [temp release];
    }
    if (elements != nil) {
        [elements release];
    }

    [super dealloc];
}


// NSXMLParser delegate implementation


- (void)parserDidStartDocument:(NSXMLParser *)parser
{
    if (elements != nil) {
        [elements release];
    }
    elements = [[NSMutableArray alloc] init];
    if (tempElement != nil) {
        [tempElement release];
        tempElement = nil;
    }
    if (temp != nil) {
        [temp release];
        temp = nil;
    }
    if (rootElement != nil) {
        [rootElement release];
        rootElement = nil;
    }
}


- (void)parserDidEndDocument:(NSXMLParser *)parser
{
   if (elements != nil) {
        [elements release];
        elements = nil;
    }
    if (tempElement != nil) {
        [tempElement release];
        tempElement = nil;
    }
    if (temp != nil) {
        [temp release];
        temp = nil;
    }
}


- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qualifiedName
    attributes:(NSDictionary *)attributeDict
{
    XMLNode *element = [[[XMLNode alloc] initWithName:elementName] autorelease];
    [element setAttributes:attributeDict];
    if (tempElement != nil) {
        [tempElement addChild:element];
        [elements addObject:tempElement];
        [tempElement release];
    } else {
        rootElement = [element retain];
    }

    tempElement = [element retain];
    if (temp != nil) {
        [temp release];
    }
    temp = [[NSMutableString alloc] init];
}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
  namespaceURI:(NSString *)namespaceURI
 qualifiedName:(NSString *)qName
{
    [tempElement setContent:temp];
    [temp release];
    temp = nil;
    [tempElement release];
    tempElement = nil;
    if ([elements count] > 0) {
        tempElement = [[elements lastObject] retain];
        [elements removeLastObject];
    }
}


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (temp != nil) {
        [temp appendString:string];
    }
}

@end

-

//
//  XMLNode.h
//

#import <Foundation/Foundation.h>

/**
 * XMLNode represents an XML data node.
 *
 * Every node can contain multiple children, attributes, a content string
 * and an element name. An XML document is represented using a reference
 * to the document root node.
 * @ingroup Webservice
 */
@interface XMLNode : NSObject {

    NSMutableArray *children;
    NSDictionary *attributes;
    NSString *content;
    NSString *elementName;

}

/**
 * Return an initialized XMLNode.
 * @param name The element name of the node.
 */
- (id)initWithName:(NSString *)name;

/**
 * Set the node attributes.
 * @param dictionary A dictionary containing the attributes.
 */
- (void)setAttributes:(NSDictionary *)dictionary;

/**
 * Set the content as string.
 * @param string The content as string.
 */
- (void)setContent:(NSString *)string;

/**
 * Add a child node.
 * @param xmlElement The child node.
 */
- (void)addChild:(XMLNode *)xmlElement;

/**
 * Return a specific attribute.
 * @param name The attribute name.
 * @return The attribute for the specified name or nil.
 */
- (NSString *)attributeForName:(NSString *)name;

/**
 * Return a child at a specific index.
 * 
 * If the index is out of the bounds, an NSRangeException is thrown.
 * @param index The position of the child (by document order).
 * @return The child at index
 * @see childElementsCount
 */
- (XMLNode *)childElementAtIndex:(int)index;

/**
 * Return a child with a certain name.
 * @param name The name of the element.
 * @return The element or nil if not available.
 */
- (XMLNode *)childWithName:(NSString *)name;
- (XMLNode *)childWithName:(NSString *)name atIndex:(NSInteger)index;

/** 
 * Return the number of child nodes.
 * @return The number of child nodes.
 */
- (int)childElementsCount;
- (int)childWithNameElementsCount:(NSString *)name;

/** 
 * Return the node content.
 * @return The node content as string.
 */
- (NSString *)content;

/**
 * Get the name of the xml element.
 * @return The name of the element.
 */
- (NSString *)name;

- (void)dealloc;

@end

-

//
//  XMLNode.m
//

#import "XMLNode.h"


@implementation XMLNode
- (id)initWithName:(NSString *)name
{
    self = [super init];
    elementName = [name copy];
    children = [[NSMutableArray alloc] init];
    return self;
}


- (void)setAttributes:(NSDictionary *)dictionary
{
    if (attributes != nil) {
        [attributes release];
    }
    attributes = [dictionary retain];
}


- (void)setContent:(NSString *)string
{
    if (content != nil) {
        [content release];
    }
    content = [string retain];
}

- (void)addChild:(XMLNode *)xmlElement
{
    [children addObject:xmlElement];
}


- (NSString *)attributeForName:(NSString *)name
{
    return [attributes objectForKey:name];
}


- (XMLNode *)childElementAtIndex:(int)index
{
    return [children objectAtIndex:index];
}


- (XMLNode *)childWithName:(NSString *)name
{
    int i;
    for (i=0; i < [children count]; ++i) {
        XMLNode *child = [children objectAtIndex:i];
        if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) {
            return child;
        }
    }

    return nil;
}

- (XMLNode *)childWithName:(NSString *)name atIndex:(NSInteger)index
{
    int i;
    int count = 0;
    for (i = 0; i < [children count]; ++i) {
        XMLNode *child = [children objectAtIndex:i];
        if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) {
            if (count == index)
                return child;
            count ++;
        }
    }

    return nil;
}

- (int)childElementsCount
{
    return [children count];
}

- (int)childWithNameElementsCount:(NSString *)name
{
    int i;
    int count = 0;
    for (i = 0; i < [children count]; ++i) {
        XMLNode *child = [children objectAtIndex:i];
        if ([[[child name] lowercaseString] isEqualToString:[name lowercaseString]]) {
            count ++;
        }
    }

    return count;
}


- (NSString *)content
{
    return content;
}


- (NSString *)name
{
    return elementName;
}


- (void)dealloc
{
    if (content != nil) {
        [content release];
    }
    if (children != nil) {
        [children release];
    }
    if (attributes != nil) {
        [attributes release];
    }

    [super dealloc];
}

@end

按如下方式使用(此示例用于分析 RSS 提要:

XMLParser *parser = [[XMLParser alloc] init];
NSObject *rss = [parser parseData:rssFeed];
feedItems = [(XMLNode *)rss childWithName:@"channel"];
if (feedItems) {
    NSLog(@"%@",[[feedItems childWithName:@"title"] content]);
}
[parser release];

如果您需要更复杂的分析,请检查 XMLNode.h 以获取更多方法

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NSXMLParser 从 XML 标签中检索错误数据 的相关文章

  • Swift:Tableview 在导航栏下方滚动但在状态栏上方滚动?

    我使用以下技巧隐藏了导航栏的阴影 self navigationController navigationBar setBackgroundImage UIImage for default self navigationControlle
  • 单击按钮时退出应用程序 - iOS [重复]

    这个问题在这里已经有答案了 可能的重复 iOS 4 0 中退出应用程序 https stackoverflow com questions 3097244 exit application in ios 4 0 我有一个 AlertView
  • iPhone 的翻译器?

    我对为 iPhone 制作一个解释器很感兴趣 这将是一个实验性的想法 但可能会很棒 我喜欢让我自 己的语言适合移动计算和数学的想法 我查阅了很多资料 发现有关 iPhone 上的口译员的信息很复杂 苹果会允许什么 我见过这个应用程序 这是一
  • 在 Xcode 中查找未使用的文件

    我最近开始开发一个新应用程序 它基本上是我以前制作的应用程序的副本 但做了一些更改 为了制作这个新应用程序 我复制了旧应用程序并删除了一些不需要的内容 我想知道 有没有办法知道 Xcode 中正在使用哪些类文件 或者有什么关于如何查找未使用
  • Apple 由于崩溃而拒绝了我的应用程序,无法重现它

    我刚刚上传了一个应用程序到应用程序商店 它是为ios 7开发的 他们拒绝了该应用程序 因为我无法重现崩溃 他们向我发送了这份崩溃报告 Exception Type EXC BAD ACCESS SIGSEGV Exception Subty
  • 无法在 xcode 8 beta 6 上编译 AWS CustomIdentityProvider

    我在 iOS 应用程序中使用 Amazon Cognito 和 Facebook 登录 直到 beta 5 为止此代码从这个SO线程 https stackoverflow com questions 37597388 aws cognit
  • JAXB 继承冲突 - 重新注释子类

    目前我的项目中有这样的环境 public abstract class Foo private List
  • 为什么 Apple 建议以编程方式创建模态导航控制器?

    以模态方式呈现导航控制器时 以编程方式创建和配置导航控制器对象通常更简单 虽然您也可以使用 Interface Builder 来执行此操作 但通常不建议这样做 事实上 因为我的导航控制器很简单 我宁愿在IB中自定义视图 虽然我不知道确切的
  • SDK 和 iOS 部署目标。

    我使用最新的 SDK 4 1 构建项目并设置 iOS 部署目标 3 0 如果我使用4 0 sdk的某些方法 我可以在真正的iPhone 3 0上运行我的项目吗 您只能在 OS 3 设备上运行您的项目 如果有条件地编码围绕您想要使用的 OS
  • iOS 有 INTERNET 权限吗?

    我在 iOS 设备上的 flutter dio 包上遇到了一个奇怪的问题 我编写了一个向 url 发送 GET 请求的应用程序 Android 上一切正常 但 iOS 上的请求似乎无法通过 没有发生任何错误 什么也没有 我在 Android
  • 使用 Dirac 在 iPhone 中进行实时音高变化 [重复]

    这个问题在这里已经有答案了 可能的重复 iPhone 上的实时音调变换 https stackoverflow com questions 1100495 real time pitch shifting on the iphone 我已经
  • 膨胀类 android.support.design.widget.NavigationView 时出错

    我按照 NavigationView 的教程进行操作 但无法解决此错误消息 Error inflating class android support design widget NavigationView 教程链接 https www
  • 如何将设备上未保存的图片上传到dropbox帐户?(IOS)

    Dropbox RestClient 仅保存文件 所以我想先将图像保存在本地文件夹中 然后上传它 结果它保存了文件 但它已损坏 NSString localPath NSBundle mainBundle pathForResource I
  • 将 NSFetchedResultsController 添加到项目后出现问题

    我设置 CoreData 时没有NSFetchedResultsController一切都保存得很好 切换到之后NSFetchedResultsController 我在尝试保存图像时遇到奇怪的错误 这是我用来保存图像的代码 void sa
  • 如何从第二个视图弹回到根视图?

    我使用 2 将 3 个视图 根视图 第 1 个视图 第 2 个视图 连接在一起modal在 Apple Watch 故事板中继续 1 在根视图中 按下 保存 按钮后 将显示第一个模态视图 2 在第一模态视图中 一旦按下 500 按钮 将显示
  • 解析根元素内元素之间的 XML 文本

    我正在尝试用 Python 解析 XML 以下是 XML 结构的示例 a aaaa1 b bbbb b aaaa2 a
  • iOS 搜索栏不显示结果

    更新 这实际上有效 我的自定义单元格的样式尚未出现 因此单元格看起来是空白的 那我怎样才能得到searchResultsTableView使用我的自定义单元格 我在表格视图中实现了搜索栏 当我调试时搜索 过滤所有工作 但是当我在搜索栏中输入
  • 隐藏 UITableview 单元格

    我正在尝试从 UITableView 中隐藏单元格 就像删除操作一样 但我只想隐藏它以便稍后在相同位置显示它 我知道 UITableViewCell 有一个名为 隐藏 的属性 但是当我使用此属性隐藏单元格时 它会隐藏但没有动画 并且会留下空
  • 具有隐式授权的 OAuth 应用程序中的客户端模拟

    来自 OAuth 草案 隐式section https datatracker ietf org doc html draft ietf oauth v2 31 section 1 3 2 在隐式授权流程期间发出访问令牌时 授权服务器不对客
  • iOS 目标 c 中的 AES/CBC/PKCS5Padding 结果与 Android 不同

    我在 Android 应用程序中使用 AES CBC PKCS5Padding 代码就像 private static String TRANSFORMATION AES CBC PKCS5Padding private static St

随机推荐