Java에서 XML을 HTML로 변환

1. 소개

이 튜토리얼에서는 일반적인 Java 라이브러리와 템플릿 엔진 (JAXP, StAX, Freemarker, Mustache)을 사용하여 XML을 HTML로 변환 하는 방법을 설명합니다 .

2. 비 정렬 화를위한 XML

HTML로 변환하기 전에 적절한 Java 표현으로 비 정렬화할 간단한 XML 문서부터 시작하겠습니다. 몇 가지 주요 목표를 염두에 두겠습니다.

  1. 모든 샘플에 대해 동일한 XML 유지
  2. 마지막에 구문 상 및 의미 상 유효한 HTML5 문서 만들기
  3. 모든 XML 요소를 텍스트로 변환

간단한 Jenkins 알림을 샘플 XML로 사용하겠습니다.

  [email protected] Build #7 passed Success: The Jenkins CI build passed 

그리고 그것은 매우 간단합니다. 여기에는 루트 요소와 일부 중첩 요소가 포함됩니다.

HTML 파일을 만들 때 모든 고유 한 XML 태그를 제거하고 키-값 쌍을 인쇄하는 것을 목표로합니다.

3. JAXP

JAXP (Java Architecture for XML Processing)는 추가 DOM 지원을 통해 널리 사용되는 SAX 구문 분석기의 기능을 확장하기위한 라이브러리입니다. JAXP는 SAX Parser를 사용하여 POJO에서 XML 정의 객체마샬링 및 언 마샬링 하는 기능을 제공합니다 . 또한 내장 DOM 도우미를 사용할 것입니다.

JAXP에 대한 Maven 종속성을 프로젝트에 추가해 보겠습니다.

 javax.xml jaxp-api 1.4.2  

3.1. DOM 빌더를 사용한 언 마샬링

먼저 XML 파일을 Java Element 객체 로 비 정렬 화하는 것으로 시작하겠습니다 .

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); factory.setFeature("//apache.org/xml/features/disallow-doctype-decl", true); Document input = factory .newDocumentBuilder() .parse(resourcePath); Element xml = input.getDocumentElement(); 

3.2. 맵에서 XML 파일 내용 추출

이제 XML 파일의 관련 콘텐츠로 을 작성해 보겠습니다 .

Map map = new HashMap(); map.put("heading", xml.getElementsByTagName("heading") .item(0) .getTextContent()); map.put("from", String.format("from: %s", xml.getElementsByTagName("from") .item(0) .getTextContent())); map.put("content", xml.getElementsByTagName("content") .item(0) .getTextContent());

3.3. DOM 빌더를 사용한 마샬링

XML을 HTML 파일로 마샬링하는 것은 좀 더 복잡합니다.

HTML을 작성하는 데 사용할 전송 문서 를 준비합시다 .

Document doc = factory .newDocumentBuilder() .newDocument(); 

다음으로 요소문서 를 채울 것입니다 .

Element html = doc.createElement("html"); Element head = doc.createElement("head"); html.setAttribute("lang", "en"); Element title = doc.createElement("title"); title.setTextContent(map.get("heading")); head.appendChild(title); html.appendChild(head); Element body = doc.createElement("body"); Element from = doc.createElement("p"); from.setTextContent(map.get("from")); Element success = doc.createElement("p"); success.setTextContent(map.get("content")); body.appendChild(from); body.appendChild(success); html.appendChild(body); doc.appendChild(html); 

마지막으로 TransformerFactory를 사용하여 Document 객체를 마샬링 해 보겠습니다 .

TransformerFactory transformerFactory = TransformerFactory.newInstance(); transformerFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true); transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_DTD, ""); transformerFactory.setAttribute(XMLConstants.ACCESS_EXTERNAL_STYLESHEET, ""); try (Writer output = new StringWriter()) { Transformer transformer = transformerFactory.newTransformer(); transformer.transform(new DOMSource(doc), new StreamResult(output)); }

output.toString () 을 호출 하면 HTML 표현을 얻게됩니다.

공장에서 설정 한 일부 추가 기능과 속성은 XXE 주입을 피하기 위해 OWASP 프로젝트의 권장 사항에서 가져온 것입니다 .

4. StAX

사용할 수있는 또 다른 라이브러리는 StAX (Streaming API for XML)입니다. JAXP와 마찬가지로 StAX는 2004 년부터 오랫동안 사용되어 왔습니다.

다른 두 라이브러리는 XML 파일 구문 분석을 단순화합니다. 간단한 작업이나 프로젝트에는 좋지만 반복해야하거나 요소 파싱 자체에 대한 명시적이고 세분화 된 제어가 필요한 경우 에는 적합하지 않습니다 . StAX가 유용합니다.

StAX API에 대한 Maven 종속성을 프로젝트에 추가해 보겠습니다.

 javax.xml.stream stax-api 1.0-2  

4.1. StAX를 사용한 언 마샬링

간단한 반복 제어 흐름을 사용하여 XML 값을 Map저장합니다 .

XMLInputFactory factory = XMLInputFactory.newInstance(); factory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE); factory.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE); XMLStreamReader input = null; try (FileInputStream file = new FileInputStream(resourcePath)) { input = factory.createXMLStreamReader(file); Map map = new HashMap(); while (input.hasNext()) { input.next(); if (input.isStartElement()) { if (input.getLocalName().equals("heading")) { map.put("heading", input.getElementText()); } if (input.getLocalName().equals("from")) { map.put("from", String.format("from: %s", input.getElementText())); } if (input.getLocalName().equals("content")) { map.put("content", input.getElementText()); } } } } finally { if (input != null) { input.close(); } }

4.2. StAX를 사용한 마샬링

이제, 우리 사용할 수 있도록 지도 하고 HTML에서 쓰기 :

try (Writer output = new StringWriter()) { XMLStreamWriter writer = XMLOutputFactory .newInstance() .createXMLStreamWriter(output); writer.writeDTD(""); writer.writeStartElement("html"); writer.writeAttribute("lang", "en"); writer.writeStartElement("head"); writer.writeDTD(""); writer.writeStartElement("title"); writer.writeCharacters(map.get("heading")); writer.writeEndElement(); writer.writeEndElement(); writer.writeStartElement("body"); writer.writeStartElement("p"); writer.writeCharacters(map.get("from")); writer.writeEndElement(); writer.writeStartElement("p"); writer.writeCharacters(map.get("content")); writer.writeEndElement(); writer.writeEndElement(); writer.writeEndDocument(); writer.flush(); }

JAXP 예제와 마찬가지로 output.toString () 을 호출 하여 HTML 표현을 얻을 수 있습니다.

5. 템플릿 엔진 사용

HTML 표현을 작성하는 대신 템플릿 엔진을 사용할 수 있습니다. Java 에코 시스템에는 여러 옵션이 있습니다. 그들 중 일부를 살펴 보겠습니다.

5.1. Apache Freemarker 사용

Apache FreeMarker는 템플릿 및 변경 데이터를 기반으로 텍스트 출력 (HTML 웹 페이지, 이메일, 구성 파일, 소스 코드 등)을 생성하기위한 Java 기반 템플릿 엔진입니다.

이를 사용하려면 Maven 프로젝트에 freemarker 종속성을 추가해야합니다.

 org.freemarker freemarker 2.3.29 

먼저 FreeMarker 구문을 사용하여 템플릿을 생성 해 보겠습니다.

    ${heading}   

${from}

${content}

이제 맵을 재사용하고 템플릿의 틈을 메 우자 :

Configuration cfg = new Configuration(Configuration.VERSION_2_3_29); cfg.setDirectoryForTemplateLoading(new File(templateDirectory)); cfg.setDefaultEncoding(StandardCharsets.UTF_8.toString()); cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); cfg.setLogTemplateExceptions(false); cfg.setWrapUncheckedExceptions(true); cfg.setFallbackOnNullLoopVariable(false); Template temp = cfg.getTemplate(templateFile); try (Writer output = new StringWriter()) { temp.process(staxTransformer.getMap(), output); }

5.2. 콧수염 사용

Mustache is a logic-less template engine. Mustache can be used for HTML, config files, source code — pretty much anything. It works by expanding tags in a template using values provided in a hash or object.

To use it, we'll need to add the mustache dependency to our Maven project:

 com.github.spullara.mustache.java compiler 0.9.6 

Let's start creating a template using the Mustache syntax:

    {{heading}}   

{{from}}

{{content}}

Now, let's fill the template with our map:

MustacheFactory mf = new DefaultMustacheFactory(); Mustache mustache = mf.compile(templateFile); try (Writer output = new StringWriter()) { mustache.execute(output, staxTransformer.getMap()); output.flush(); }

6. The Resulting HTML

In the end, with all our code samples, we'll get the same HTML output:

    Build #7 passed   

from: [email protected]

Success: The Jenkins CI build passed

7. Conclusion

In this tutorial, we've learned the basics of using JAXP, StAX, Freemarker, and Mustache to convert XML into HTML.

For more information about XML in Java, check out these other great resources right here on Baeldung:

  • Deserializing XML to Objects in XStream
  • Serializing Objects to XML in XStream
  • Java XML Libraries

항상 그렇듯이 여기에 표시된 전체 코드 샘플은 GitHub에서 사용할 수 있습니다.