2012-02-24 44 views
1

我想解析一個log4j生成的xml日誌。在xml中是一個帶有throwable的節點(如果有的話)。這個(多行,標籤)文本被封裝在一個CDATA標籤中。Groovys XmlParser忽略CDATA CR/CL

這是整個文件的摘錄:

<log4j:event logger="org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver" timestamp="1330083921521" level="ERROR" thread="http-8080-1"> 
<log4j:message><![CDATA[Exception occurred when processing request: [GET] /test/log/show 
Stacktrace follows:]]></log4j:message> 
<log4j:throwable><![CDATA[org.xml.sax.SAXParseException: XML document structures must start and end within the same entity. 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231) 
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522) 
    at test.LogController$_closure2.doCall(LogController.groovy:21) 
    at test.LogController$_closure2.doCall(LogController.groovy) 
    at java.lang.Thread.run(Thread.java:662) 
]]></log4j:throwable> 
</log4j:event> 

我groovys XmlParser的解析它:

def parser = new XmlParser(false, false).parse(new File("stack.log")) 

return parser.'log4j:event'.collect { l -> 
    LogEntry entry = new LogEntry() 
    entry.with { 
     level = l.'@level' 
     message = l.'log4j:message'.text() 
     thread = l.'@thread' 
     logger = l.'@logger' 
     timestamp = new Date(l.'@timestamp' as long) 
     throwable = l.'log4j:throwable'?.text() ?: '' 
    } 
    entry 
} 

的 '拋出' 字段包含的所有文字,但沒有CR/LF。

有人知道如何應對嗎?

謝謝您的優先...

+0

你有沒有一點XML的例子? – 2012-02-24 14:47:33

+0

我編輯帖子以顯示一個小例子... – matcauthon 2012-02-24 16:27:07

回答

1

討厭就在你扔的代碼,但似乎按預期方式工作,並返回CRLFs

def xml = '''<log> 
      | <log4j:event logger="org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver" timestamp="1330083921521" level="ERROR" thread="http-8080-1"> 
      | <log4j:message><![CDATA[Exception occurred when processing request: [GET] /test/log/show 
      |Stacktrace follows:]]></log4j:message> 
      | <log4j:throwable><![CDATA[org.xml.sax.SAXParseException: XML document structures must start and end within the same entity. 
      | at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231) 
      | at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522) 
      | at test.LogController$_closure2.doCall(LogController.groovy:21) 
      | at test.LogController$_closure2.doCall(LogController.groovy) 
      | at java.lang.Thread.run(Thread.java:662) 
      |]]></log4j:throwable> 
      | </log4j:event> 
      |</log>'''.stripMargin() 


class LogEntry { 
    def level 
    def message 
    def thread 
    def logger 
    def timestamp 
    def throwable 

    String toString() { 
    """EVENT: 
     | level : $level 
     | message : $message 
     | thread : $thread 
     | logger : $logger 
     | ts  : $timestamp 
     | thrown : $throwable""".stripMargin() 
    } 
} 

def parser = new XmlParser(false, false).parseText(xml) 
def entries = parser.'log4j:event'.collect { event -> 
    new LogEntry().with { 
    level  = [email protected] 
    message = event.'log4j:message'.text() 
    thread = [email protected] 
    logger = [email protected] 
    timestamp = new Date([email protected] as long) 
    throwable = event.'log4j:throwable'?.text() ?: '' 
    it 
    } 
} 

entries.each { 
    println it 
} 

,打印:

EVENT: 
    level : ERROR 
    message : Exception occurred when processing request: [GET] /test/log/show 
Stacktrace follows: 
    thread : http-8080-1 
    logger : org.codehaus.groovy.grails.web.errors.GrailsExceptionResolver 
    ts  : Fri Feb 24 11:45:21 GMT 2012 
    thrown : org.xml.sax.SAXParseException: XML document structures must start and end within the same entity. 
    at com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1231) 
    at com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522) 
    at test.LogController$_closure2.doCall(LogController.groovy:21) 
    at test.LogController$_closure2.doCall(LogController.groovy) 
    at java.lang.Thread.run(Thread.java:662) 

其中在它具有CRLF字符,他們都應該是...

這是與Groovy 1.8.6 btw ...你使用什麼版本?你可以升級並重試嗎?

+0

嗯。 Yepp,我正在使用1.7.10(在Grails上)。使用1.8.6進行測試,它按預期工作。 – matcauthon 2012-02-25 11:56:57

+0

好的。看來,我的控制器和視圖之間我錯過了翻譯標籤等... – matcauthon 2012-02-28 12:46:46

0

xml標準要求在解析過程中將空白區域標準化。

我不確定,但解析器可能有一個設置來覆蓋此行爲。否則,您可以預處理文件,用它們的xml實體替換c數據部分中的行結尾,然後解析它。

+0

-1。除了屬性外,XML標準不會調用要標準化的空白。 – lavinio 2012-02-24 15:14:28