2023-03-25-TIL
2023-03-25-TIL
Today I Learned
Parsing HTML in Java with Jsoup
jsoup은 실제 웹에서 볼 수 있는 HTML과 XML을 다루는 자바 라이브러리다. WHATWG HTML5 명세를 구현해서 최신 브라우저와 같은 DOM으로 파싱하고, DOM 탐색이나 CSS 선택자로 데이터를 찾을 수 있다. 사용자가 입력한 HTML을 허용 목록(safelist) 기준으로 정리해 XSS를 막는 기능도 있다(jsoup).
1
2
3
Document doc = Jsoup.parse(html);
Elements links = doc.select("a[href]");
String safe = Jsoup.clean(userHtml, Safelist.basic());
브라우저와 같은 방식으로 파싱한다는 점이 중요하다. 닫는 태그가 빠진 HTML도 브라우저가 해석하는 것과 같은 트리로 만들어 주므로, 정규식으로 태그를 자르는 것보다 훨씬 안전하다. 에디터에서 넘어온 HTML을 서버에 저장하기 전에 clean으로 허용된 태그만 남기는 용도로도 쓸 수 있다.
- https://www.baeldung.com/java-with-jsoup
ProseMirror
FE에서 HTML 텍스트를 그대로 받을수도 있겠지만, HTML 구조를 JSON으로 파싱해서 전달받는 방법도 있다. 그것을 도와주는 도구가 바로 ProseMirror이다. 이렇게 파싱된 JSON 형식으로 HTML 문서를 받으면 저장하기도 용이하고 다루기도 용이하다.
ProseMirror는 웹 기반 리치 텍스트 에디터를 만드는 툴킷이다. 문서를 HTML 문자열이 아니라 자체 노드 트리로 표현한다. 가이드는 ProseMirror 문서를 0개 이상의 자식 노드를 담은 프래그먼트를 가진 노드라고 설명한다. 문서에 어떤 노드가 올 수 있는지는 스키마(schema)가 정하고, 굵게나 링크 같은 서식은 마크(mark)로 노드에 붙는다(ProseMirror Guide: Documents).
브라우저 DOM과 다른 점은 인라인 내용을 다루는 방식이다. <p>a<strong>b</strong></p>가 DOM에서는 중첩 트리지만, ProseMirror에서는 텍스트 노드의 평평한 나열에 마크가 메타데이터로 붙는다. 같은 마크를 가진 인접 텍스트 노드는 항상 합쳐지므로, 같은 내용의 문서는 표현이 하나로 정해진다.
저장과 전송은 JSON으로 한다. 노드에 toJSON을 호출하면 JSON.stringify에 그대로 넘길 수 있는 객체가 나오고, 스키마의 nodeFromJSON으로 다시 문서를 만든다. HTML이 필요하면 스키마에 정의한 규칙으로 DOMParser, DOMSerializer를 써서 변환한다.
1
2
3
4
5
6
7
8
9
10
{
"type": "doc",
"content": [
{ "type": "paragraph",
"content": [
{ "type": "text", "text": "a" },
{ "type": "text", "text": "b", "marks": [{ "type": "strong" }] }
] }
]
}
HTML 문자열로 저장하면 서버가 내용을 이해하려면 매번 파싱해야 하고, 허용하지 않은 태그가 섞일 위험도 있다. 스키마를 따르는 JSON으로 저장하면 구조가 스키마로 제한되고, 서버에서도 문단이나 링크 같은 요소를 바로 다룰 수 있다. 위의 jsoup과 함께 보면, 이미 HTML로 쌓인 데이터는 jsoup으로 정리하고 새 에디터 데이터는 ProseMirror JSON으로 받는 식의 조합도 생각해 볼 수 있다.
- https://prosemirror.net/docs/guide/#doc
댓글
아직 댓글이 없습니다