안드로이드 개발 질문/답변
(글 수 45,052)
htmlcleaner 와 DOM parser 를 이용해 개발중입니다.
http get 메소드로 요청을 해 얻어온 결과를 xml 로 저장하여 파싱할 때와 String 으로 받아와 파싱할 때의 값이 틀립니다.,
현재 테스트중인 내용이 결과값을 htmlcleaner 의 writeXmlToFile 로 xml 로 저장하여 파싱을 해보고
정상적으로 파싱이 되기에 결과값을 String으로 받아와 파싱을 해보려는데 이게 안되네요.
String으로 변환하는 과정은
1. 요청으로 돌아오는 값을 String 값으로 받습니다. (생성자 HttpGet())
2. 아래 정규식으로 script 항목을 제거했습니다.
3. script 가 제거된 값을 htmlcleaner 를 이용해 xml 형식으로 변환합니다. (HttpGet 클래스의 parse 메소드 이용)
4. 그 후 DOM Parser 를 이용해서 파싱 합니다.
문제는 위에서 말씀드렸다시피 htmlcleaner 의 writeXmlToFile 메소드로 xml 파일 저장 후 파싱시 값이 정상적으로 나오는데
제가 작성한 HttpGet 의 parse 메소드로 String 화 하여 파싱을 하니 Fatal Error 라는 메세지가 출력됩니다.
에러 메세지는
[Fatal Error] :2:1469: Element type "img" must be followed by either attribute specifications, ">" or "/>".
org.xml.sax.SAXParseException: Element type "img" must be followed by either attribute specifications, ">" or "/>".
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:249)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:284)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:124)
at http.pasing.DomParse.<init>(Http.java:311) <<-- 여기가 doc = builder.parse(istream); 이부분입니다.
at http.pasing.ParsingText.main(ParsingText.java:20)
doc SAX error
Exception in thread "main" java.lang.NullPointerException
at http.pasing.DomParse.<init>(Http.java:322)
at http.pasing.ParsingText.main(ParsingText.java:20)
ByteArrayOutputStream 객체인 ostream 을 toString() 시킨 값과 동일하게 만들어진 xml 파일의 내용이 동일합니다.
헌데 이런 오류가 발생하네요. ostream 의 String 화가 잘못된 건가요?
ByteArrayOutputStream 은 처음 써보는지라...
질문 내용이 엄청 기네요;;;
수고스러우시겠지만 도움 부탁드립니다 ㅠ ㅠ
ps : 앱에서는 xml 파일 생성이 아예 불가능한건가요? 임시로 sd 카드에 잠시 기록했다 지우는 방법은 없는건가요? 요것도 부탁드립니다;
http get 메소드로 요청을 해 얻어온 결과를 xml 로 저장하여 파싱할 때와 String 으로 받아와 파싱할 때의 값이 틀립니다.,
현재 테스트중인 내용이 결과값을 htmlcleaner 의 writeXmlToFile 로 xml 로 저장하여 파싱을 해보고
정상적으로 파싱이 되기에 결과값을 String으로 받아와 파싱을 해보려는데 이게 안되네요.
String으로 변환하는 과정은
1. 요청으로 돌아오는 값을 String 값으로 받습니다. (생성자 HttpGet())
class HttpGet{ URL url; HttpURLConnection huc; BufferedReader bf; String line = null; String result = null; String result2 = null; StringBuilder builder; ByteArrayOutputStream ostream = new ByteArrayOutputStream(); HtmlCleaner cleaner; CleanerProperties props; TagNode node = null; public HttpGet(){ try { builder = new StringBuilder(); url = new URL("요청_URL"); huc = (HttpURLConnection)url.openConnection(); huc.setUseCaches(false); bf = new BufferedReader(new InputStreamReader(huc.getInputStream(), "UTF-8")); while ((line = bf.readLine()) != null) builder.append(line); result = builder.toString(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (Exception e){ e.printStackTrace(); } } public String getResult(){ return result; } public String parse(String str){ cleaner = new HtmlCleaner(); props = cleaner.getProperties(); try { node = cleaner.clean(str); } catch (IOException e) { e.printStackTrace(); } SimpleXmlSerializer se = new SimpleXmlSerializer(props); try { se.writeXmlToStream(node, ostream, "UTF-8"); }catch (IOException e) { e.printStackTrace(); } result2 = ostream.toString(); return result2; } }
2. 아래 정규식으로 script 항목을 제거했습니다.
class ClearDocu { private static interface Patterns { public static final Pattern SCRIPTS = Pattern.compile( "<(no)?script[^>]*>.*?</(no)?script>", Pattern.DOTALL); public static final Pattern STYLE = Pattern.compile( "<style[^>]*>.*</style>", Pattern.DOTALL); public static final Pattern Blank = Pattern.compile("\n\n", Pattern.DOTALL); } public String clean(String str) { if (str == null) { return null; } Matcher mat; mat = Patterns.SCRIPTS.matcher(str); str = mat.replaceAll(""); mat = Patterns.STYLE.matcher(str); str = mat.replaceAll(""); mat = Patterns.Blank.matcher(str); str = mat.replaceAll(""); return str; } }
3. script 가 제거된 값을 htmlcleaner 를 이용해 xml 형식으로 변환합니다. (HttpGet 클래스의 parse 메소드 이용)
4. 그 후 DOM Parser 를 이용해서 파싱 합니다.
class DomParse{ File file; DocumentBuilderFactory factory; DocumentBuilder builder; InputStream istream; Document doc; Element root, sub_root; NodeList items, children; Node item, text, index; String[] ItemName = new String[4]; public DomParse(String name){ factory = DocumentBuilderFactory.newInstance(); try { builder = factory.newDocumentBuilder(); } catch (ParserConfigurationException e) { e.printStackTrace(); System.err.println("factory error"); } try { istream = new ByteArrayInputStream(name.getBytes("UTF-8")); } catch (UnsupportedEncodingException e) { e.printStackTrace(); System.err.println("istream error"); } try { doc = builder.parse(istream); } catch (SAXException e) { e.printStackTrace(); System.err.println("doc SAX error"); } catch (IOException e) { System.err.println("doc ioe error"); e.printStackTrace(); } root = doc.getDocumentElement(); // 파싱 내용 생략 } }
문제는 위에서 말씀드렸다시피 htmlcleaner 의 writeXmlToFile 메소드로 xml 파일 저장 후 파싱시 값이 정상적으로 나오는데
제가 작성한 HttpGet 의 parse 메소드로 String 화 하여 파싱을 하니 Fatal Error 라는 메세지가 출력됩니다.
에러 메세지는
[Fatal Error] :2:1469: Element type "img" must be followed by either attribute specifications, ">" or "/>".
org.xml.sax.SAXParseException: Element type "img" must be followed by either attribute specifications, ">" or "/>".
at com.sun.org.apache.xerces.internal.parsers.DOMParser.parse(DOMParser.java:249)
at com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderImpl.parse(DocumentBuilderImpl.java:284)
at javax.xml.parsers.DocumentBuilder.parse(DocumentBuilder.java:124)
at http.pasing.DomParse.<init>(Http.java:311) <<-- 여기가 doc = builder.parse(istream); 이부분입니다.
at http.pasing.ParsingText.main(ParsingText.java:20)
doc SAX error
Exception in thread "main" java.lang.NullPointerException
at http.pasing.DomParse.<init>(Http.java:322)
at http.pasing.ParsingText.main(ParsingText.java:20)
ByteArrayOutputStream 객체인 ostream 을 toString() 시킨 값과 동일하게 만들어진 xml 파일의 내용이 동일합니다.
헌데 이런 오류가 발생하네요. ostream 의 String 화가 잘못된 건가요?
ByteArrayOutputStream 은 처음 써보는지라...
질문 내용이 엄청 기네요;;;
수고스러우시겠지만 도움 부탁드립니다 ㅠ ㅠ
ps : 앱에서는 xml 파일 생성이 아예 불가능한건가요? 임시로 sd 카드에 잠시 기록했다 지우는 방법은 없는건가요? 요것도 부탁드립니다;
2010.07.28 06:28:08
에러를 보시면.. xml의 문법오류.. 가 의심되는 상황이죠.
이런 상황이라면.. 아마도 예상에 저 위에 정규식 쓰시는 부분에서
뭔가 잘못되지 않았을까 하는 생각이 살짝 들구요..
ClearDocu 를 한 직후의 내용을 파일에 써서 한번 보시면 될거같네요..
xml파일 생성을 물어보신건 아마 그래서 그런건가 싶긴 한데..
Environment.getExternal~~() 로 sdcard의 root를 가져오시고 거기다가 파일 생성하시면 되구요
sd카드를 쓰기 위해서는 write external storage 였나 하는 permission 을 추가해 주셔야 합니다.,
2010.07.28 09:32:05
Darklake // 네... ClearDocu 한 후의 파일로는 문제없이 파싱이 됩니다 ㅠ ㅠ
파일과 String 의 내용이 같은데도 왜 저런 오류가 생기는건지...
ClearDocu 클래스는 정상적으로 동작합니다.(저도 어디서 퍼와서 쓰는거지만 ㅎㅎㅎ;;;)
아무래도 알려주신 방법대로 sd카드에 xml 파일을 임시로 생성하는 방법을 찾아봐야겠네요.
답변 감사합니다~~
파일과 String 의 내용이 같은데도 왜 저런 오류가 생기는건지...
ClearDocu 클래스는 정상적으로 동작합니다.(저도 어디서 퍼와서 쓰는거지만 ㅎㅎㅎ;;;)
아무래도 알려주신 방법대로 sd카드에 xml 파일을 임시로 생성하는 방법을 찾아봐야겠네요.
답변 감사합니다~~