2009-10-09 3 views
6

У меня есть XML-файл, который использует внутренне объявленные объекты. Например:Как разрешить внутренне объявленную ссылку на сущность XML с помощью NSXMLParser

<?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: делегата будет вызываться дважды со строками:

  1. "foo"
  2. "bar"

Ссылка my_symbol объекта игнорируются. Что требуется для того, чтобы ссылка на объект была разрешена?

EDIT:

Удаление ENTITY декларации my_symbol от DTD приведет к NSXMLParserUndeclaredEntityError. Это говорит о том, что, когда присутствует объявление объекта, а затем ссылается на <my_next_element>, оно замечается. По какой-то причине это просто не разрешается для строки, которую она представляет.

Кроме того, если в элементе используется &amp;, синтаксический анализатор будет корректно разрешать его до "&", и он передается как строка при вызове метода делегата parser:foundCharacters:.

+0

Сейчас я сталкиваюсь с этой проблемой. Вы решили это? –

+0

вы можете найти его с помощью [XPath] (http://en.wikipedia.org/wiki/XPath)? –

+0

Я выполнил запрос XPath на «my_element», и оба «foo» и «bar» также не были разрешены. Правильно ли указывать внутренне объявленные объекты, как я это сделал? –

ответ

2

Я рассмотрел 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 

на основе порядка записей в файле это выглядит найденные методы декларации, как ожидается, произойдет до того, как элементы (как вы обнаружили). Я бы попытался обработать все эти методы и посмотреть, есть ли какой-либо из них, но все они выглядят так, как будто они предназначены для других целей.

Интересно, есть ли способ обработать все необработанные сообщения, отправленные вашему делегату, на случай, если документация/интерфейс неполна.

+0

Я выполнил все делегаты, согласно вашему предложению, и повторно запустил. Тем не менее, делегат не вызывается, когда парсер получает «& my_symbol;».Как уже упоминалось, удаление объявления ENTITY вызовет метод «resolveExternalEntityName», который предполагает, что он распознает его как ссылку на сущность. По какой-то причине, когда объявление ENTITY присутствует (и признано), оно просто не разрешает ссылку на стоимость объекта. –

+1

После того, как я надеюсь, что это вызов недокументированного метода, я нашел эту страницу, в которой говорится о том, как создать прокси-объект. Предположительно, вы можете бросить это перед вашим делегатом NSXMLParser и искать все, что не обрабатывалось: http://borkware.com/rants/agentm/elegant-delegation/ –

+0

Но даже если это окажется недокументированным сообщением вам нужно справиться с этим, похоже, вам нужно сообщить об ошибке Apple. Либо он должен быть документирован, либо должен быть реализован, а затем документирован. –

 Смежные вопросы

  • Нет связанных вопросов^_^