[http]XHTML Tutorial - 1.0 기준으로 다소 차이가 있을 수 있다.
[http]Changes from XHTML 1.0 Strict

1. 최상위에 DTD 선언한다.

1.0 transitional의 경우 :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

1.0 strict의 경우 :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

1.1의 경우 :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

2. html:html을 사용한다.
<html:html xhtml="true">
...
</html:html>

이것은 다음과 같이 변환되며
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">

html:text 등의 사용시 다음과 같이 명시적으로 태그를 닫아주게 된다.
<input type="text" ... />

이때 html의 lang attribute는 backword compatible만을 위해 존재하며 XHTML 1.1에서는 제거되도록 명시되어있기 때문에 validator에서 문제가 된다.
struts의 xhtml은 현재 1.0을 지원한다. [http]참고
따라서 간단한 해결책은 1.0 수준에서 검증하거나, 아래와 같이 html을 수동 구현 하는 것이다.

<html:xhtml />
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">

혹은

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko-KR">

...

html:xhtml 태그를 이용한 선언으로 위의 input 박스 등의 문제는 모두 해결할 수 있다.

3. url 사용시
<a href="/blog/comment.do?id=mmx900&articleId=12&commentId=3">
이와 같은 url은
  • cannot generate system identifier for general entity "articleId"
  • general entity "method" not defined and no default entity
  • reference not terminated by REFC delimiter
  • reference to external entity in attribute value
등의 에러를 발생시킨다.

ISO 표준에 따라 이들 &을 & a m p ;로 변환해야 하는데, jstl core 태그 라이브러리의 url은 기본으로 &을 넣어 생성한다.
이 URL을 c:out을 이용하면 & a m p ;로 변환되어 출력되지만, 달리 이용할 경우(ex: html:link나 html:form에 사용할 경우) 일일이 ${fn:escapeXml(param)}을 써 주는 수 밖에는 방법이 없다.
(문서에 따라 c:url은 자동으로 앰퍼샌드를 변환한다고도 되어 있던데 여하간 1.1.2의 jakarta taglibs standards에선 지원 안된다.)
일괄적으로, 다음과 같이 정의할수도 있다.
<c:url var="url_blog_rss" value="blog" scope="request">
  <c:param name="id" value="${param.id}" />
  <c:param name="method" value="rss" />
</c:url>
<c:set var="url_blog_rss" value="${fn:escapeXml(url_blog_rss)}" scope="request"/>
변수를 정의할 때 c:url과 c:set의 scope 를 동일하게 해 주는 것을 잊지 말자. 아무런 에러를 내지 않아도 서로 다른 결과가 나올 수 있다.


추가적인 문제해결


validator에서 다음과 같은 에러가 나올때는 황당하기 짝이 없다.
Line 136, column 6: end tag for "head" which is not finished

</head>

Most likely, You nested tags and closed them in the wrong order. For example <p><em>...</p> is not acceptable, as <em> must be closed before <p>. Acceptable nesting is: <p><em>...</em></p>

Another possibility is that you used an element (e.g. 'ul') which requires a child element (e.g. 'li') that you did not include. Hence the parent element is "not finished", not complete.