자바스크립트 코드 내에서 & 기호를 XML 엔터티인 &로 변경하는 문제
자바스크립트 코드 내에서 & 기호를 XML 엔터티인 &로 변경하는 문제
1 . 문제는 뭐지
'&&'기호를 어떻게 해석하게 하느냐의 문제군요! 늘 궁금했는데...
답: 블록 안에 넣어 파서가 내용을 무시하도록한다.
주어진 이미지와 에러 메시지를 보니, 블로그스팟 테마의 HTML 편집 시 발생하는
org.xml.sax.SAXParseException
에러는 HTML 특수 문자 처리가 원인입니다.2. 문제의 원인
블로그스팟 테마 편집기는 XML 기반의 HTML을 사용합니다. 이 환경에서는 &
기호가 XML 엔터티 참조의 시작을 의미하므로, 단순히 <div class="some-class & another-class">
와 같이 사용하면 구문 오류가 발생합니다.
이미지에서 에러가 발생한 117번째 줄을 보면 다음과 같은 코드가 있습니다.
if (mainTitle && mainTitle.nextSibling) {
이 코드는 <b:include data='blog' name='all-head-content'/>
와 같은 블로그스팟의 특별한 태그(XML)와 혼합될 때 문제가 발생할 수 있습니다. 자바스크립트 코드 내의 &&
연산자가 XML 파서에게 &
로 시작하는 엔티티 참조로 오해를 받기 때문입니다.
3. 해결책
자바스크립트 코드 내에서 &
기호를 XML 엔터티인 &
로 변경해주면 됩니다. 하지만, 자바스크립트 코드 자체를 변경하는 것보다 더 안전하고 쉬운 방법은 HTML과 자바스크립트 코드를 <![CDATA[...]]>
블록 안에 넣어 파서가 내용을 무시하도록 하는 것입니다.
아래는 수정된 코드입니다. 이 코드는 XML 파서가 자바스크립트 코드를 XML이 아닌 일반 텍스트로 인식하게 만들어줍니다.
3-1. 블로그스팟 테마용 수정 코드 (에러 해결)
1. HTML 편집기로 이동
블로그스팟 대시보드에서 '테마' > **'HTML 편집'**으로 이동합니다.
2. JavaScript 코드 수정
기존에 삽입하셨던 <script>
태그를 찾아 아래와 같이 수정합니다.
<script>
//<![CDATA[
document.addEventListener('DOMContentLoaded', function() {
const mainBody = document.querySelector('data:post.body');
const mainTitle = document.querySelector('h1.post-title');
const tocContainer = document.createElement('div');
tocContainer.className = 'toc-container';
const tocTitle = document.createElement('h2');
tocTitle.className = 'toc-title';
tocTitle.innerHTML = '목차 <span class="toggle-icon">▼</span>';
const tocContent = document.createElement('div');
tocContent.className = 'toc-content';
const tocList = document.createElement('ul');
tocList.id = 'toc-list';
const headers = document.querySelectorAll('h2, h3');
if (headers.length > 0) {
headers.forEach((header, index) => {
const headerId = 'toc-' + index;
header.id = headerId;
const li = document.createElement('li');
li.innerHTML = `<a href="#${headerId}">${header.innerText}</a>`;
if (header.tagName.toLowerCase() === 'h2') {
li.className = 'toc-h2';
} else if (header.tagName.toLowerCase() === 'h3') {
li.className = 'toc-h3';
}
tocList.appendChild(li);
});
tocContent.appendChild(tocList);
tocContainer.appendChild(tocTitle);
tocContainer.appendChild(tocContent);
// 목차를 게시글 제목 바로 아래에 삽입
if (mainTitle && mainTitle.nextSibling) {
mainTitle.parentNode.insertBefore(tocContainer, mainTitle.nextSibling);
} else if (mainBody) {
mainBody.parentNode.insertBefore(tocContainer, mainBody);
}
// 목차 접기/펼치기 기능 추가
tocTitle.addEventListener('click', function() {
const isHidden = tocContent.style.display === 'none' || tocContent.style.display === '';
tocContent.style.display = isHidden ? 'block' : 'none';
const toggleIcon = this.querySelector('.toggle-icon');
toggleIcon.innerText = isHidden ? '▲' : '▼';
});
}
});
//]]>
</script>
수정된 부분:
<script>
태그의 시작과 끝에 //<![CDATA[
**와 **//]]>
를 추가했습니다. 이 블록은 XML 파서에게 "이 안의 내용은 XML 구문이 아니라 일반 텍스트이므로 문법 검사를 하지 마라"고 지시하는 역할을 합니다. 이렇게 하면 &
와 같은 특수 문자가 에러를 일으키는 것을 방지할 수 있습니다.
파서가 궁금하지는 않는거조!!
3. 요약
요약하면, 에러가 발생했던&&
연산자 자체를 수정하는 것보다, 자바스크립트 코드 블록 전체를 <![CDATA[]]>
로 감싸는 것이 더 안전하고 간편한 해결책입니다. 이 방법으로 에러를 해결하고 원하는 목차 기능을 구현할 수 있습니다.