收集NSXMLDocument报警输出
我有以下的辅助功能通过XSLT转换XML:收集NSXMLDocument报警输出
- (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;
}
它正常工作,但有一个轻微的怪癖,我可以使用援助。
当我尝试使用XSLT功能是未知NSXMLDocument(比如,EXSLT的node-set()
),我得到在Xcode输出类似下面 - 第一线,特别是利益:
xmlXPathCompOpEval: function node-set not found
XPath error: Unregistered function runtime
error: element for-each
Failed to evaluate the 'select' expression.
很酷;这正是我所期望的。
然而,我感兴趣的是,输出不包含任何地方的"Error: "
(如果输出已被我的[xmlDocErr localizedDescription]
调用捕获,应该是这种情况)。
所以,这里的问题:我怎样才能抓住上述输出(以便我可以用它来显示相关消息给我的用户)?
非常感谢!
的误差内libxml
深情况的发生,在线路的xpath.c
13479,这结束了对error.c
71行,打印到stderr
主叫xmlGenericErrorDefaultFunc()
。因此,要做到这一点最简单的方法是捕获stderr
,而XSLT处理是怎么回事:
- (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;
}
但是,这是一个黑客位的,所以要小心......
如果你不对该解决方案感到满意的话,应该可以使用xmlerror.h
的第864行的initGenericErrorDefaultFunc
替代使用自己的自定义错误处理函数的变量xmlGenericError
(默认情况下,其参考号为xmlGenericErrorDefaultFunc
)。这会更安全,但也更复杂(如果可能的话)。
太棒了,@SimonM - 感谢您的挖掘。我会玩,看看我想出了什么。 – ABach