2008-10-13 1 views
2

Java를 사용하여 원격 장치에서 생성 된 진행중인 이벤트 드라이브 XML 스트림을 구문 분석하려고합니다. 여기에 두 이벤트의 단순화 된 예제이다 : 나는 삭스와 같은 익숙한 아니에요하지만 그것은, 지속적인 스트림이기 때문에 SAX는 DOM에 비해이 더 적합한 것 같다Java에서 "이벤트 XML"을 구문 분석하는 방법은 무엇입니까?

<?xml version="1.0"?> 
<Event> DeviceEventMsg 
<Param1>SomeParmValue</Param1> 
</Event> 
<?xml version="1.0"?> 
<Event> DeviceEventMsg 
<Param1>SomeParmValue</Param1> 
</Event> 

. XML 구조에 대해 저를 부르짖 지 마십시오. 이미 알고 있으며 변경할 수 없습니다.

그리고 예, 장치는 모든 이벤트 전에 xml 지시어를 보냅니다. 내 첫 번째 문제는 두 번째 xml 처리 명령이 SAX 파서를 왜곡한다는 것입니다.

아무도 그 문제를 해결할 방법을 제안 할 수 있습니까?


두 번째 XML 처리 명령에 운다되어 지금까지 사용하고있는 코드는 다음과 같습니다

public class TestMe extends HandlerBase { 
    public void startDocument() throws SAXException 
    { 
     System.out.println("got startDocument"); 
    } 

    public void endDocument() throws SAXException 
    { 
     System.out.println("got endDocument"); 
    } 

    public void startElement (String name, AttributeList attrs) throws SAXException 
    { 
     System.out.println("got startElement"); 
    } 

    public void endElement (String name) throws SAXException 
    { 
     System.out.println("got endElement"); 
    } 

    public void characters (char buf [], int offset, int len) throws SAXException 
    { 
     System.out.println("found characters"); 
    } 

    public void processingInstruction (String target, String data) throws SAXException 
    { 
     System.out.println("got processingInstruction"); 
    } 

    public static void main(String[] args) { 
     SAXParserFactory factory = SAXParserFactory.newInstance(); 
     try { 
      SAXParser saxParser = factory.newSAXParser(); 
      // using a file as test input for now 
      saxParser.parse(new File("devmodule.xml"), new TestMe()); 

     } catch (Throwable err) { 
      err.printStackTrace(); 
     } 
    } 
} 
+0

데이터 스트림은 얼마나 빨리 업데이트됩니까? XML 헤더간에 연결이 끊어 졌습니까? – simon

+0

이벤트는 홈 오토메이션 장치의 켜기/끄기 이벤트이므로 몇 초 간격이 될 수 있지만 길게 활동하지는 않습니다. 이벤트는 연결간에 유지됩니다. –

답변

1

시도 대신 SAX의 StAX을 사용합니다. StAX는 훨씬 더 많은 유연성을 제공하며 스트리밍 XML을위한 더 나은 솔루션입니다. StAX의 구현이 거의 없습니다. codehaus에 매우 만족하지만, Sun도 있습니다. 문제가 해결 될 수도 있습니다.

+0

STAX에게 내가 입력 한 중간에있는 행에 barf가 아닌 것을 알려주는 방법을 알고 있습니까? 다시 장치가 제공하는 것으로 고정되어 있으며 변경할 수 없습니다. –

0

당신은 시작과 끝 요소에서 System.out.println()이 같은 것을 얻을 것이다의 이름을 인쇄하는 경우 :

가 있으며, StartDocument가하는 startElement 이벤트 문자가 문자의 startElement Param1을 가지고 발견 발견 가지고 있어요 발견 자하는 endElement Param1을 는 문자하는 endElement 이벤트 org.xml.sax.SAXParseException있어 발견 얻었다 : 일치 처리 명령 대상 "[XX] [mm의 [LL]는"허용되지 않는다. ...

그래서 나는로부터 endDocument가 파서 문제를 일으키는받지 않고 두 번째

<?xml version="1.0"?>

생각합니다.

0

이 추가하는 경우 : 다른 캐치하기 전에

catch(SAXException SaxErr){ 
     System.out.println("ignore this error"); 
    } 

당신이 특정 오류를 잡을 것입니다. 그런 다음 장치를 다시 열어야하거나 정적 파일의 경우 파일에 있는지 추적해야 할 수 있습니다.

마지막 이벤트 이벤트에서 장치/파일을 닫은 후 다음 이벤트를 위해 다시 엽니 다.

0

RE : 사이먼 (Simon)이 ​​SAXException을 잡아서 하나의 XML 문서가 끝났을 때를 결정하고 다른 문서의 시작 부분에 도달했다면 문제가되는 접근 방법이라고 생각합니다. 어떤 이유로 든 다른 오류가 발생하면 오류가있는 XML로 인해 예외가 발생했는지 또는 문서의 끝에 도달했는지 여부를 알 수 없습니다.

문제는 파서가 XML 문서를 처리하기위한 것입니다. 여러 XML 문서의 스트림이 아닙니다. 들어오는 데이터 스트림을 수동으로 파싱하여 단일 XML 문서가 포함 된 개별 스트림으로 분할하는 코드를 작성하는 것이 좋습니다. 이러한 스트림을 XML 구문 분석기에 직렬로 전달하여 이벤트의 순서를 보장 할 수 있습니다.

+0

하나의 연속 된 입력 스트림을 통해 들어오는 일련의 XML 문서를 잡는 XML 파서가 있습니까? –

+1

XML 파서는 올바른 형식의 XML 문서를 구문 분석하도록 설계되었습니다 (기술적으로는 일부는 문서 조각을 처리 할 수 ​​있음). 가지고있는 것은 잘 구성된 XML 문서가 아닙니다. – ykaganovich

+0

@sgreeve, 제 의견으로는이 특정 오류를 확인하는 방법이나 문서 끝에 오류를 처리하는 방법이 있습니다. 당신의 제안은 xml 파서로 전달되기 전에 잘 만들어진 문서 또는 문서로 미리 파싱 (알려진 패턴을 찾아서)하는 것이 좋습니다. – simon

1

하나 이상의 제안 사항, 특히 여러 xml 선언과 관련하여. 예, 이것은 불법 XML입니다. 따라서 적절한 파서가 기본 모드를 사용하여 barf로 바뀌게됩니다. 그러나 일부 파서에는 대체 "다중 문서"모드가 있습니다.

기본적으로 http://www.cowtowncoder.com/blog/archives/2008/04/entry_66.html

, 당신은 그 입력이 "여러 XML 문서"의 형태 (입력 공장을 통해) 파서 말할 필요 (ParsingMode.PARSING_MODE_DOCUMENTS)를 예를 들어, Woodstox이있다, 그래서 당신은 체크 아웃 할 수있다 .

그렇다면 여러 xml 선언을 허용하며 각 선언은 새 문서의 시작을 나타냅니다.