[마이바티스] MyBatis 비교연산 시 XML 파싱 오류 (org.xml.sax.SAXParseException)
Caused by: org.apache.ibatis.builder.BuilderException: Error creating document instance.
Cause: org.xml.sax.SAXParseException; lineNumber: 118; columnNumber: 88;
The content of elements must consist of well-formed character data or markup.
◆ 발생에러
입력한 날짜(시작일, 종료일)에 해당하는 콘텐츠를 검색하는 Select문을 MyBatis Mapper파일(XML)에 작성하면서
시작일을 입력한 경우는 갱신일 컬럼값이 시작일보다 크거나 같은, 종료일을 입력한 경우는 갱신일 컬럼값이 종료일보다 작거나 같은 콘텐츠를 찾는 Where조건을 줬는데 위와 같은 XML 파싱오류가 발생하였다.
<if test="beginDate != null and endDate == null">
and to_char(a.updDate, 'YYYYMMDD') >= #{beginDate}
</if>
<if test="beginDate == null and endDate != null">
and to_char(a.updDate, 'YYYYMMDD') <= #{endDate}
</if>
◆ 원인
org.apache.ibatis.builder.BuilderException과 같은 예외가 발생하는 것은 MyBatis의 매퍼 파일에 XML 파싱 오류가 있을 때 주로 나타나기 때문에 해당 XML파일의 잘못된 마크업이나 잘못된 문법을 포함하고 있는 쿼리를 찾아보니 비교 연산자에서 문법 오류가 발생하고 있었다.
에러메시지를 잘 살펴보면 알겠지만 >= 과 <= 를 비교연산자가 아닌 XML표준문법으로 인식되면서 문제가 발생했다.
The content of elements must consist of well-formed character data or markup.
(요소 콘텐츠는 올바른 형식의 문자 데이터 또는 마크업으로 구성되어야 합니다.)
그럼 왜 비교연산자 중 >=는 문제가 없고 <=만 문제가 됐을까?
결론부터 말하면 둘 다 문제였다.
>=는 >를 태그의 마지막 닫는 부분으로 해석하므로 XML문법 오류를 일으키지는 않았지만 비교연산자로 인식되던 것은 아니었고, <=는 <를 포함하고 있어서 XML파서가 이를 태그의 시작으로 해석하려고 해서 오류가 발생했었다.
◆ 해결방안
1. CDATA 블록을 사용하여 작성
CDATA는 character data(문자데이터)를 의미하는데 CDATA로 문자를 감싸면 그 안의 데이터는 마크업으로 해석되지 않는다.
<![CDATA[적용할 문자열]]>
<![CDATA[>=]]>
(변경 전) and to_char(a.updDate, 'YYYYMMDD') >= #{beginDate}
(변경 후) and to_char(a.updDate, 'YYYYMMDD') <![CDATA[>=]]> #{beginDate}
<![CDATA[<=]]>
(변경 전) and to_char(a.updDate, 'YYYYMMDD') <= #{endDate}
(변경 후) and to_char(a.updDate, 'YYYYMMDD') <![CDATA[<=]]> #{endDate}
2. HTML엔티티를 사용하여 작성
HTML엔티티 코드를 사용하여 XML문법오류를 피할 수 있다.
< 는 < 로 변경
(변경 전) and to_char(a.updDate, 'YYYYMMDD') >= #{beginDate}
(변경 후) and to_char(a.updDate, 'YYYYMMDD') <= #{beginDate}
> 는 > 로 변경
(변경 전) and to_char(a.updDate, 'YYYYMMDD') <= #{endDate}
(변경 후) and to_char(a.updDate, 'YYYYMMDD') >= #{endDate}
참조
Class SAXParseException
https://docs.oracle.com/javase/8/docs/api/org/xml/sax/SAXParseException.html
엔터티 (Entity)
https://developer.mozilla.org/ko/docs/Glossary/Entity
글 내용 중 잘못된 부분이 있거나, 첨부하실 내용이 있으시면 댓글로 남겨주세요. 공부하는데 많은 도움이 됩니다.
-- 기억의 유효기간은 생각보다 짧다. --