2017-12-07 16 views
0

아래는자바/그루비 :

import java.io.File; 
import java.io.IOException; 

import javax.xml.XMLConstants; 
import javax.xml.transform.stream.StreamSource; 
import javax.xml.validation.Schema; 
import javax.xml.validation.SchemaFactory; 
import javax.xml.validation.Validator; 
import javax.xml.transform.sax.SAXSource 
import javax.xml.parsers.SAXParserFactory 
import org.xml.sax.SAXException 
import org.xml.sax.InputSource 
import org.xml.sax.SAXParseException 
import org.xml.sax.ErrorHandler 


def validateXMLSchema(String xsdPath, String xmlPath) { 
    final List <SAXParseException> exceptions = new LinkedList <SAXParseException>(); 
    try { 
     SchemaFactory factory = 
     SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI); 
     Schema schema = factory.newSchema(new File(xsdPath)); 
     Validator validator = schema.newValidator(); 
     validator.setErrorHandler(new ErrorHandler() { 
     @Override 
     public void warning(SAXParseException exception) throws SAXException { 
     exceptions.add(exception); 
     } 

     @Override 
     public void fatalError(SAXParseException exception) throws SAXException { 
     exceptions.add(exception); 
     } 

     @Override 
     public void error(SAXParseException exception) throws SAXException { 
     exceptions.add(exception); 
     } 
     }); 
     def xmlFile = new File(xmlPath); 
     validator.validate(new StreamSource(xmlFile)); 
     exceptions.each { 
     println 'lineNumber : ' + it.lineNumber + '; message : ' + it.message 
     } 
    } catch (IOException | SAXException e) { 
     println("Exception: line ${e.lineNumber} " + e.getMessage()); 
     return false; 
    } 
    return exceptions.size() == 0; 
} 

아래는 유효성 검사 오류 중 일부 XSD를 맞아야 XML 스키마를 검증하는 내 그루비 코드 라인 수에 의하여 XML 노드를 찾아, 나는 각 메시지의 줄 번호를 액세스 할 수 있으며 해당 노드 이름

lineNumber : 106; message : cvc-datatype-valid.1.2.1: '' is not a valid value for 'date'. 
lineNumber : 248; message : cvc-enumeration-valid: Value 'Associate' is not facet-valid with respect to enumeration '[ADJSTR, ADJSMT] 

줄 번호를 usinng 오류 메시지가 corresponsding에 대한 노드 이름을 찾을 수있는 간단한 방법이 있나요을 찾기 위해 노력하고 있어요? 아니면 특정 라인을 읽고 아래처럼 XmlSlurper를 사용하여 파싱해야합니까 (사용자로드가 많은 프로덕션 환경에서 더 큰 XML 파일의 경우 느려지므로이 접근법을 피하십시오).

def getNodeName(xmlFile, lineNumber){ 
    def xmlLine = xmlFile.readLines().get(lineNumber) 
    def node = new XmlSlurper().parseText(xmlLine.toString()) 
    node.name() 
} 
+0

xml을 열고 해당 권장 사항을 변경해야합니다. – Rao

+0

[Java 8/Groovy : XSD로 XML 유효성 검사 및 예외 또는 유효성 검사 오류에 대한 노드 찾기] (https://stackoverflow.com/questions/47682190/java-8-groovy-validate-xml-with)의 가능한 복제본 -an-xsd-and-an-exception-for-an-an-aa) – cfrick

답변

1

이 우아한 아니지만 다음 getNodeName()은 (full example here) 빨리해야한다 :

def getNodeName(xmlFile, lineNumber) { 
    def result = "unknown" 
    def count = 1 
    def NODE_REGEX = /.*?<(.*?)>.*/ 
    def br 

    try { 
     br = new BufferedReader(new FileReader(xmlFile)) 
     String line 
     def isDone = false 
     while ((! isDone) && (line = br.readLine()) != null) { 
      if (count == lineNumber) { 
       def matcher = (line =~ NODE_REGEX) 
       if (matcher.matches()) { 
        result = matcher[0][1] 
       } 
       isDone = true 
      } 
      count++ 
     } 
    } finally { 
     // TODO: better exception handling 
     br.close() 
    } 

    return result 
} 

그것은 단순히 문제의 라인까지 라인을 읽은 다음 이름을 얻을 수있는 기초적인 정규 표현식을 사용합니다. 원하는 경우 예제에서와 같이 잠재적으로 XmlSlurper을 사용할 수 있습니다. 핵심은 파일 IO/메모리가 상당히 적어야한다는 것입니다.