收集NSXMLDocument警告输出

时间:2013-04-17 15:54:21

标签: objective-c cocoa nserror nsxml nsxmldocument

我有以下帮助函数,用于通过XSLT转换XML:

- (NSXMLDocument *)transform:(NSString *)xml :(NSString *)xslt
{
    NSError *xmlDocErr = nil;
    NSXMLDocument *transformedXmlDoc = nil;

    NSXMLDocument *xmlDoc = [[NSXMLDocument alloc]
                              initWithXMLString:xml
                              options:NSXMLDocumentValidate
                              error:&xmlDocErr];

    if (xmlDocErr) {
        NSLog(@"Error: %@", [xmlDocErr localizedDescription]);
    }
    else {
        transformedXmlDoc = [xmlDoc objectByApplyingXSLTString:xslt 
                                    arguments:nil
                                    error:&xmlDocErr];
        if (xmlDocErr) {
            NSLog(@"Error: %@", [xmlDocErr localizedDescription]);
        }
    }

    return transformedXmlDoc;
}

它按预期工作,但有一点点怪癖我可以使用。

当我尝试使用NSXMLDocument未知的XSLT函数(比如EXSLTnode-set())时,我在Xcode中输出类似于下面的内容 - 第一行,特别是感兴趣:

  

xmlXPathCompOpEval:找不到函数node-set

     

XPath错误:未注册的函数运行时

     

错误:元素为每个

     

无法评估'select'表达式。

那很酷;这正是我所期待的。

然而,有趣的是,输出在任何地方都不包含"Error: "(如果我的[xmlDocErr localizedDescription]调用已经捕获了该输出,则应该是这种情况)。

所以,问题是:我如何获取上述输出(以便我可以使用它向我的用户显示相关消息)?

非常感谢!

1 个答案:

答案 0 :(得分:1)

错误发生在libxml深处xpath.c的第13479行,最终在error.c的第71行调用xmlGenericErrorDefaultFunc(),打印到{{1} }}。因此,最简单的方法是在XSLT处理过程中捕获stderr

stderr

但这有点像黑客,所以要小心......

如果您对该解决方案不满意,应该可以使用您自己的自定义错误处理函数覆盖变量- (NSXMLDocument *)transform:(NSString *)xml :(NSString *)xslt { NSError *xmlDocErr = nil; NSXMLDocument *transformedXmlDoc = nil; NSXMLDocument *xmlDoc = [[NSXMLDocument alloc] initWithXMLString:xml options:NSXMLDocumentValidate error:&xmlDocErr]; if (xmlDocErr) { NSLog(@"Error: %@", [xmlDocErr localizedDescription]); } else { // Pipe for stderr NSPipe *pipe = [NSPipe pipe]; // Duplicate of stderr (will use later) int cntl = fcntl(STDERR_FILENO,F_DUPFD); // Redirect stderr through our pipe dup2([[pipe fileHandleForWriting] fileDescriptor], STDERR_FILENO); transformedXmlDoc = [xmlDoc objectByApplyingXSLTString:xslt arguments:nil error:&xmlDocErr]; // Get the data NSData *dat = [[pipe fileHandleForReading] availableData]; // Redirect stderr through our duplicate, to restore default output behavior dup2(cntl, STDERR_FILENO); // Did anything get logged? if ([dat length]>0) { NSLog(@"Error: %@", [[NSString alloc] initWithData:dat encoding:NSASCIIStringEncoding]); } if (xmlDocErr) { NSLog(@"Error: %@", [xmlDocErr localizedDescription]); } } return transformedXmlDoc; } (默认情况下引用xmlGenericErrorxmlerror.h第864行的xmlGenericErrorDefaultFunc。这样会更安全,但也更复杂(如果可能的话)。