0

我对这个堆栈跟踪感到很困惑(只显示了令人困惑的部分):

-[NSXMLDocument length]: unrecognized selector sent to instance 0x10187e010
An uncaught exception was raised
-[NSXMLDocument length]: unrecognized selector sent to instance 0x10187e010
(
   0   CoreFoundation                      0x00007fff8f5d6286 __exceptionPreprocess + 198
   1   libobjc.A.dylib                     0x00007fff9213bd5e objc_exception_throw + 43
   2   CoreFoundation                      0x00007fff8f6624ce -[NSObject doesNotRecognizeSelector:] + 190
   3   CoreFoundation                      0x00007fff8f5c3133 ___forwarding___ + 371
   4   CoreFoundation                      0x00007fff8f5c2f48 _CF_forwarding_prep_0 + 232
   5   CoreFoundation                      0x00007fff8f548c66 CFDataGetLength + 118
   6   CoreFoundation                      0x00007fff8f5791df CFStringCreateFromExternalRepresentation + 31
   7   asLJ                                0x0000000100013828 +[stripHTML stripAllHtmlFromString:] + 212

特别是,我不明白调用在哪里CFStringCreateFromExternalRepresentation发生,所以我不知道我的代码 ( +[stripHTML stripAllHtmlFromString:]) 的哪一部分导致了异常。是什么导致调用CFStringCreateFromExternalRepresentation?如果很明显,我做错了什么导致异常?将来,我该如何确定调用的是CFStringCreateFromExternalRepresentation什么?

这是+[stripHTML stripAllHtmlFromString:]

+ (NSString *)stripAllHtmlFromString:(NSString *)inputString
{
    // based on code from http://sugarmaplesoftware.com/25/strip-html-tags/#comment-71

    NSError *theError = NULL;
    NSString *modifiedInputString = [NSString stringWithFormat:@"%@\n\n\n\n\n\n\n\n\n\n\n\n",inputString]; // adding some spare newlines at the end to ensure that things will work even with a short non-HTML string
    NSXMLDocument *theDocument = [[NSXMLDocument alloc] initWithXMLString:modifiedInputString
                                                                  options:NSXMLDocumentTidyHTML
                                                                    error:&theError];

    NSString *theXSLTString = @"<?xml version='1.0' encoding='utf-8'?>"
                                "<xsl:stylesheet version='1.0' xmlns:xsl='http://www.w3.org/1999/XSL/Transform' xmlns:xhtml='http://www.w3.org/1999/xhtml'>"
                                "<xsl:output method='text'/>"
                                "<xsl:template match='xhtml:head'></xsl:template>"
                                "<xsl:template match='xhtml:script'></xsl:template>"
                                "</xsl:stylesheet>";    
    NSData *theData = [theDocument objectByApplyingXSLTString:theXSLTString arguments:NULL error:&theError];
    [theDocument release];
    return [[[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding] autorelease];
}
4

2 回答 2

3

哦,实际上,可能-objectByApplyingXSLTString:arguments:error:返回了一个NSXMLDocument而不是一个NSData. 因此,调用 to-[NSString initWithData:encoding:]调用-length它认为是的NSData,但NSXMLDocument不承认这一点。

于 2012-05-20T00:06:17.053 回答
0

Ken Thomases 的回答似乎完全正确——出于某种原因,对于非常短的输入(特别是空字符串),-objectByApplyingXSLTString:arguments:error:给定的 XSLT 返回一个NSXMLDocument(尽管我认为它不应该)。为了修复它,我首先检测我们是否得到了一个NSXMLDocument,如果有,则将其转换为 XML 的字符串表示形式并将其反馈给方法;否则假设我们得到了NSData我们最初预期的结果。

用下面的代码替换给定方法的最后 3 行(从NSData *theData =...开始)似乎已经解决了这个问题。

// Had a report of an exception that seemed to indicate objectByApplyingXSLTString:arguments:error: was returning an NSXMLDocument objectinstead of an NSData object, so let's guard against that.  (discussed at https://stackoverflow.com/q/10669479/291280 )
NSObject *XSTLresult = [theDocument objectByApplyingXSLTString:theXSLTString arguments:NULL error:&theError];
[theDocument release];
if ([XSTLresult isKindOfClass:[NSXMLDocument class]]) {
    // If the result is an NSXMLDocument, call XMLData to get an NSData object, turn it into a string, and feed that back into this method...
    return [self stripAllHtmlFromString:[[[NSString alloc]
                                          initWithData:[(NSXMLDocument *)XSTLresult XMLData]
                                          encoding:NSUTF8StringEncoding]
                                         autorelease]
            ];
} else {
    // Otherwise, assume we have an NSData object.
    return [[[NSString alloc] initWithData:(NSData *)XSTLresult encoding:NSUTF8StringEncoding] autorelease];
}
于 2012-05-20T05:16:00.777 回答