如何使用NSXMLParser解析内部声明的XML实体引用 [英] How to resolve an internally-declared XML entity reference using NSXMLParser

查看:179
本文介绍了如何使用NSXMLParser解析内部声明的XML实体引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个使用内部声明的实体的XML文件。例如:

I have an XML file that uses internally-declared entities. For example:

<?xml version="1.0" encoding="UTF-8"?>

...

<!ENTITY my_symbol "my symbol value">

...

<my_element>
    <my_next_element>foo&my_symbol;bar</my_next_element>
</my_element>

...

使用NSXMLParser类,我怎么能够解析 my_symbol 实体引用?

Using the NSXMLParser class, how am I able to resolve the my_symbol entity reference?

从实验中,解析器:foundInternalEntityDeclarationWithName:value: 将为 my_symbol 实体声明调用委托方法,值我的符号值。然后,当达到 my_next_element 元素时, NSXMLParser 将调用解析器:didStartElement:namespaceURI :qualifiedName:attributes:委托方法。

From experimentation, the parser:foundInternalEntityDeclarationWithName:value: delegate method will be called for the my_symbol entity declaration, with value "my symbol value". Then, when the my_next_element element is reached, NSXMLParser will call the parser:didStartElement:namespaceURI:qualifiedName:attributes: delegate method.

之前解析器:didEndElement:namespaceURI:qualifiedName:被调用< / my_next_element> 解析器:foundCharacters:委托方法将被调用两次字符串:

Before parser:didEndElement:namespaceURI:qualifiedName: is called for </my_next_element>, the parser:foundCharacters: delegate method will be called twice with the strings:


  1. foo

  2. bar

  1. "foo"
  2. "bar"

my_symbol 实体引用被忽略。为了解析实体参考需要什么?

The my_symbol entity reference is ignored. What is required in order for the entity reference to be resolved?

编辑:

删除 ENTITY 从DTD声明 my_symbol 将导致 NSXMLParserUndeclaredEntityError 。这表明当实体声明存在,然后在< my_next_element> 中引用时,它会被注意到。出于某种原因,它只是没有被解析为它代表的字符串。

Removing the ENTITY declaration of my_symbol from the DTD will result in an NSXMLParserUndeclaredEntityError. This suggests that when the entity declaration is present, and then referenced in <my_next_element>, it is being noticed. For some reason it's just not being resolved to the string it represents.

此外,如果& amp; 是在一个元素中使用,解析器将正确地将其解析为&,当解析器:foundCharacters:调用委托方法。

Also, if &amp; is used within an element, the parser will correctly resolve it to "&" and this is passed as the string when the parser:foundCharacters: delegate method is called.

推荐答案

我查看了NSXMLParser.h,其中列出了以下为委托提供支持的已定义方法:

I reviewed NSXMLParser.h which lists the following defined methods for delegates to support:

@interface NSObject (NSXMLParserDelegateEventAdditions)
// Document handling methods
- (void)parserDidStartDocument:(NSXMLParser *)parser;
    // sent when the parser begins parsing of the document.
- (void)parserDidEndDocument:(NSXMLParser *)parser;
    // sent when the parser has completed parsing. If this is encountered, the parse was successful.

// DTD handling methods for various declarations.
- (void)parser:(NSXMLParser *)parser foundNotationDeclarationWithName:(NSString *)name publicID:(NSString *)publicID systemID:(NSString *)systemID;

- (void)parser:(NSXMLParser *)parser foundUnparsedEntityDeclarationWithName:(NSString *)name publicID:(NSString *)publicID systemID:(NSString *)systemID notationName:(NSString *)notationName;

- (void)parser:(NSXMLParser *)parser foundAttributeDeclarationWithName:(NSString *)attributeName forElement:(NSString *)elementName type:(NSString *)type defaultValue:(NSString *)defaultValue;

- (void)parser:(NSXMLParser *)parser foundElementDeclarationWithName:(NSString *)elementName model:(NSString *)model;

- (void)parser:(NSXMLParser *)parser foundInternalEntityDeclarationWithName:(NSString *)name value:(NSString *)value;

- (void)parser:(NSXMLParser *)parser foundExternalEntityDeclarationWithName:(NSString *)name publicID:(NSString *)publicID systemID:(NSString *)systemID;

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;
    // sent when the parser finds an element start tag.
    // In the case of the cvslog tag, the following is what the delegate receives:
    //   elementName == cvslog, namespaceURI == http://xml.apple.com/cvslog, qualifiedName == cvslog
    // In the case of the radar tag, the following is what's passed in:
    //    elementName == radar, namespaceURI == http://xml.apple.com/radar, qualifiedName == radar:radar
    // If namespace processing >isn't< on, the xmlns:radar="http://xml.apple.com/radar" is returned as an attribute pair, the elementName is 'radar:radar' and there is no qualifiedName.

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
    // sent when an end tag is encountered. The various parameters are supplied as above.

- (void)parser:(NSXMLParser *)parser didStartMappingPrefix:(NSString *)prefix toURI:(NSString *)namespaceURI;
    // sent when the parser first sees a namespace attribute.
    // In the case of the cvslog tag, before the didStartElement:, you'd get one of these with prefix == @"" and namespaceURI == @"http://xml.apple.com/cvslog" (i.e. the default namespace)
    // In the case of the radar:radar tag, before the didStartElement: you'd get one of these with prefix == @"radar" and namespaceURI == @"http://xml.apple.com/radar"

- (void)parser:(NSXMLParser *)parser didEndMappingPrefix:(NSString *)prefix;
    // sent when the namespace prefix in question goes out of scope.

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
    // This returns the string of the characters encountered thus far. You may not necessarily get the longest character run. The parser reserves the right to hand these to the delegate as potentially many calls in a row to -parser:foundCharacters:

- (void)parser:(NSXMLParser *)parser foundIgnorableWhitespace:(NSString *)whitespaceString;
    // The parser reports ignorable whitespace in the same way as characters it's found.

- (void)parser:(NSXMLParser *)parser foundProcessingInstructionWithTarget:(NSString *)target data:(NSString *)data;
    // The parser reports a processing instruction to you using this method. In the case above, target == @"xml-stylesheet" and data == @"type='text/css' href='cvslog.css'"

- (void)parser:(NSXMLParser *)parser foundComment:(NSString *)comment;
    // A comment (Text in a <!-- --> block) is reported to the delegate as a single string

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock;
    // this reports a CDATA block to the delegate as an NSData.

- (NSData *)parser:(NSXMLParser *)parser resolveExternalEntityName:(NSString *)name systemID:(NSString *)systemID;
    // this gives the delegate an opportunity to resolve an external entity itself and reply with the resulting data.

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;
    // ...and this reports a fatal error to the delegate. The parser will stop parsing.

- (void)parser:(NSXMLParser *)parser validationErrorOccurred:(NSError *)validationError;
    // If validation is on, this will report a fatal validation error to the delegate. The parser will stop parsing.
@end

根据文件中条目的顺序,它查找找到的声明方法预计会在找到元素之前发生(正如您所发现的那样)。我会尝试处理所有这些方法,看看是否有任何这些方法,但它们看起来都像是为其他用途设计的。

Based on the order of entries in the file it looks the found declaration methods are expected to occur before the elements are found (as you've discovered). I'd try handling all of these methods and see if any of them occur, but they all look like they are designed for other uses.

我想知道是否有方法来检测发送给您的委托的所有未处理的消息,以防文档/接口不完整。

I wonder if there is a way to instrument all the unhandled messages sent to your delegate just in case the documentation/interface is incomplete.

这篇关于如何使用NSXMLParser解析内部声明的XML实体引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆