8

内部で宣言されたエンティティを使用する 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エンティティ宣言に対して valueで呼び出されます"my symbol value"。次に、my_next_element要素に到達すると、デリゲート メソッドNSXMLParserが呼び出されます。parser:didStartElement:namespaceURI:qualifiedName:attributes:

parser:didEndElement:namespaceURI:qualifiedName:for が呼び出される前</my_next_element>に、parser:foundCharacters:デリゲート メソッドが文字列で 2 回呼び出されます。

  1. "foo"
  2. "bar"

my_symbolエンティティ参照は無視されます。エンティティ参照を解決するには何が必要ですか?

編集:

DTD からのENTITY宣言を削除すると、 . これは、エンティティ宣言が存在し、次に で参照されると、それが注目されていることを示唆しています。何らかの理由で、それが表す文字列に解決されていません。my_symbolNSXMLParserUndeclaredEntityError<my_next_element>

また、&amp;が要素内で使用されている場合、パーサーはそれを正しく解決し、デリゲート メソッドが呼び出され"&"たときに文字列として渡されます。parser:foundCharacters:

4

1 に答える 1

3

デリゲートがサポートする次の定義済みメソッドをリストした 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

ファイル内のエントリの順序に基づいて、見つかった宣言メソッドは、要素が見つかる前に発生すると予想されます (発見したように)。これらすべてのメソッドを処理して、それらのいずれかが発生するかどうかを確認しますが、それらはすべて他の用途のために設計されているように見えます.

ドキュメント/インターフェイスが不完全な場合に備えて、デリゲートに送信されたすべての未処理のメッセージを計測する方法があるかどうか疑問に思います。

于 2009-10-15T15:05:02.287 に答える