我有以下帮助函数,用于通过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函数(比如EXSLT的node-set()
)时,我在Xcode中输出类似于下面的内容 - 第一行,特别是感兴趣:
xmlXPathCompOpEval:找不到函数node-set
XPath错误:未注册的函数运行时
错误:元素为每个
无法评估'select'表达式。
那很酷;这正是我所期待的。
然而,有趣的是,输出在任何地方都不包含"Error: "
(如果我的[xmlDocErr localizedDescription]
调用已经捕获了该输出,则应该是这种情况)。
所以,问题是:我如何获取上述输出(以便我可以使用它向我的用户显示相关消息)?
非常感谢!
答案 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;
}
(默认情况下引用xmlGenericError
) xmlerror.h
第864行的xmlGenericErrorDefaultFunc
。这样会更安全,但也更复杂(如果可能的话)。