2009-10-09 5 views
6

Mam plik XML, który używa deklarowanych wewnątrz jednostek. Na przykład:Jak rozwiązać zadeklarowane wewnętrznie odwołanie do jednostki XML za pomocą 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> 

... 

Korzystanie z klasy NSXMLParser, jak jestem w stanie rozwiązać odniesienia my_symbol jednostki?

Z eksperymentu metoda delegata parser:foundInternalEntityDeclarationWithName:value: zostanie wywołana dla deklaracji jednostki my_symbol o wartości "my symbol value". Następnie, gdy osiągnięty zostanie element my_next_element, NSXMLParser wywoła metodę delegata parser:didStartElement:namespaceURI:qualifiedName:attributes:.

Przed parser:didEndElement:namespaceURI:qualifiedName: nazywa dla </my_next_element> metoda parser:foundCharacters: delegat zostanie wywołana dwukrotnie strun:

  1. "foo"
  2. "bar"

Odniesienie my_symbol jednostka jest ignorowany. Co jest wymagane, aby odwołanie do jednostki mogło zostać rozwiązane?

EDIT:

Zdejmowanie deklarację ENTITY z my_symbol z DTD spowoduje NSXMLParserUndeclaredEntityError. Sugeruje to, że gdy deklaracja encji jest obecna, a następnie przywoływana w <my_next_element>, jest zauważana. Z jakiegoś powodu po prostu nie jest on rozwiązany dla ciągu, który reprezentuje.

Ponadto, jeśli w elemencie użyto &amp;, parser prawidłowo rozwiąże go na "&" i zostanie przekazany jako ciąg po wywołaniu metody delegatów parser:foundCharacters:.

+0

Teraz wpadam na ten problem. Rozwiązałeś to? –

+0

możesz go znaleźć z [XPath] (http://en.wikipedia.org/wiki/XPath)? –

+0

Wykonałem kwerendę XPath na 'my_element' i oba "foo" i "bar" również nie zostały rozwiązane. Czy poprawnie jest odwoływać się do jednostek deklarowanych wewnętrznie, tak jak ja to zrobiłem? –

Odpowiedz

2

Sprawdziliśmy NSXMLParser.h który wymienia następujące metody zdefiniowane dla delegatów do poparcia:

@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 

na podstawie kolejności zgłoszeń w pliku wygląda oczekiwanego są znalezione metody deklaracji wystąpić przed elementy są znalezione (jak odkryłeś). Chciałbym spróbować obsłużyć wszystkie te metody i sprawdzić, czy którekolwiek z nich występują, ale wszystkie wyglądają tak, jakby były przeznaczone do innych zastosowań.

Zastanawiam się, czy istnieje sposób na przesłanie wszystkich nieobsługiwanych wiadomości wysłanych do twojego uczestnika, na wypadek gdyby dokumentacja/interfejs był niekompletny.

+0

Zaimplementowałem wszystkich delegatów zgodnie z sugestią i ponownie uruchomiłem. Mimo to żaden uczestnik nie jest wywoływany, gdy parser przechodzi do "& my_symbol;".Jak wspomniano, usunięcie deklaracji ENTITY wywoła metodę "resolveExternalEntityName", która sugeruje, że rozpoznaje ją jako odwołanie do encji. Z jakiegoś powodu, gdy deklaracja ENTITY jest obecna (i rozpoznawana), po prostu nie rozwiązuje odniesienia do wartości jednostki. –

+1

Kontynuując, mając nadzieję, że jest to tylko nieudokumentowane wywołanie metody, znalazłem tę stronę, która mówi o tym, jak utworzyć obiekt proxy. Prawdopodobnie możesz rzucić to przed delegata NSXMLParser i szukać wszystkiego, co nie było obsługiwane: http://borkware.com/rants/agentm/elegant-delegation/ –

+0

Ale nawet jeśli okaże się, że jest to nieudokumentowana wiadomość musisz sobie z tym poradzić, wygląda na to, że musisz zgłosić błąd firmie Apple. Musi to być udokumentowane lub musi zostać wdrożone, a następnie udokumentowane. –

Powiązane problemy