출력

2013-04-17 9 views
2

경고 NSXMLDocument 수집 I가 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; 
} 

. 나는, 나는 다음과 유사 엑스 코드의 출력을 얻을 수 (EXSLTnode-set(), 말) NSXMLDocument에 불명는 XSLT 기능을 사용하려고하면

- 첫 번째 줄, 특히를, 관심의 :

xmlXPathCompOpEval: function node-set not found

XPath error: Unregistered function runtime

error: element for-each

Failed to evaluate the 'select' expression.

멋진데; 정확히 내가 기대했던 것입니다.

그러나 재미있는 점은 출력에 "Error: "이 포함되어 있지 않다는 것입니다 (출력이 내 [xmlDocErr localizedDescription] 호출로 캡처 된 경우).

여기에 질문이 있습니다. 내 사용자에게 관련 메시지를 표시하는 데 사용할 수 있도록 위의 출력을 잡는 방법은 무엇입니까?

감사합니다.

답변

1

오류가 stderr 인화 error.c 라인 (71)에 xmlGenericErrorDefaultFunc() 호출 끝 라인의 xpath.c 13,479에, libxml 깊숙한 일어나고있다. 그래서 XSLT 처리가 진행되는 동안이 작업을 수행하는 가장 쉬운 방법은 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; 
} 

을하지만 당신이하지 않으면, 그래서

... 조심 해킹의 비트입니다 이 솔루션에 만족하면 xmlerror.h의 864 행 initGenericErrorDefaultFunc을 사용하여 사용자 정의 오류 처리 기능을 사용하여 변수 xmlGenericError (기본적으로 xmlGenericErrorDefaultFunc을 참조)을 무시할 수 있어야합니다. 그것은 훨씬 더 안전 할뿐만 아니라 더 복잡합니다 (가능하다면).

+0

환상적인 @SimonM -이 파고를 해줘서 고마워. 나는 놀아서 내가 생각해내는 것을 보게 될 것이다. – ABach