我有一个使用内部声明的实体的XML文件。 例如:
<?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
实体引用?
从实验中, parser:foundInternalEntityDeclarationWithName:value:
委托方法将被调用为my_symbol
实体声明,与价值"my symbol value"
。 然后,当my_next_element
达到元素NSXMLParser
将调用parser:didStartElement:namespaceURI:qualifiedName:attributes:
委托方法。
前parser:didEndElement:namespaceURI:qualifiedName:
被调用</my_next_element>
中, parser:foundCharacters:
委托方法进行两次与琴弦称为:
-
"foo"
-
"bar"
该my_symbol
实体引用被忽略。 为了使实体引用需要什么来解决?
编辑:
卸下ENTITY
的声明my_symbol
从DTD将导致NSXMLParserUndeclaredEntityError
。 这表明,当实体声明存在,然后在参考<my_next_element>
它是被注意到。 出于某种原因,它只是没有被解决,它代表的字符串。
另外,如果&
是一个元素中使用,分析器将正确地解析它来"&"
并且这被作为字符串传递当parser:foundCharacters:
委托方法被调用。
我回顾NSXMLParser.h其中列出了以下定义的方法为代表,以支持:
@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
根据条目顺序在文件看起来有望找到的申报方法的元素被发现之前发生(如你发现)上。 我想尝试处理所有的这些方法,看看其中是否会发生,但他们看起来都像它们被设计用于其他用途。
我不知道是否有一种方法可以仪器上的所有发送到您的委托,以防万一的文档/接口是不完整的未处理的消息。
文章来源: How to resolve an internally-declared XML entity reference using NSXMLParser