XML에서 CDATA 엔드 토큰을 이스케이프 처리하는 방법이 있습니까?
]]>
xml 문서의 CDATA 섹션 내에서 CDATA 종료 토큰 ( ) 을 이스케이프 처리하는 방법이 있는지 궁금합니다 . 또는 더 일반적으로 CDATA 내에서 사용하기위한 이스케이프 시퀀스가있는 경우 (그러나 존재하는 경우 어쨌든 시작 또는 종료 토큰을 이스케이프하는 것이 합리적이라고 생각합니다).
기본적으로 CDATA에 시작 또는 끝 토큰을 포함시키고 파서에게 해석하지 말고 다른 문자 시퀀스로 취급하도록 지시 할 수 있습니다.
아마 당신이 그것을하려고하면 XML 구조 또는 코드를 리팩터링해야하지만, 지난 3 년 동안 매일 xml을 사용해 왔지만이 문제가 없었습니다. 가능한지 궁금했습니다. 그냥 호기심.
편집하다:
HTML 인코딩을 사용하는 것 외에는 ...
분명히이 질문은 순수한 학문입니다. 다행히도 매우 명확한 답이 있습니다.
CDATA 종료 시퀀스를 이스케이프 할 수 없습니다. XML 사양 의 프로덕션 규칙 20 은 매우 분명합니다.
[20] CData ::= (Char* - (Char* ']]>' Char*))
편집 :이 제품 규칙은 문자 그대로 "CData 섹션에는 원하는 순서로 ']]>'를 포함 할 수 있습니다. 예외는 없습니다."
EDIT2 : 같은 섹션 도 읽습니다.
CDATA 섹션 내에서 CDEnd 문자열 만 마크 업으로 인식되므로 왼쪽 꺾쇠 괄호와 앰퍼샌드가 리터럴 형식으로 나타날 수 있습니다. "
<
"및 "&
"를 사용하여 이스케이프 할 필요는 없습니다 . CDATA 섹션은 중첩 할 수 없습니다.
다시 말해 엔터티 참조, 마크 업 또는 다른 형태의 해석 구문을 사용할 수 없습니다. CDATA 섹션 내에서 구문 분석 된 텍스트는 유일 ]]>
하며 섹션을 종료합니다.
따라서 ]]>
CDATA 섹션 내 에서 이스케이프 할 수 없습니다 .
EDIT3 : 같은 섹션 도 읽습니다.
2.7 CDATA 섹션
[정의 : CDATA 섹션은 문자 데이터가 발생할 수있는 모든 곳에서 발생할 수 있습니다. 이들은 마크 업으로 인식되는 문자를 포함하는 텍스트 블록을 이스케이프하는 데 사용됩니다. CDATA 섹션은 "<! [CDATA ["문자열로 시작하고 "]]>"문자열로 끝납니다.]
그러면 단일 CDATA 섹션 대신 여러 개의 인접한 CDATA 섹션을 포함하여 문자 데이터가 발생할 수있는 CDATA 섹션이있을 수 있습니다. 이를 통해 ]]>
토큰 을 분할 하고 두 부분을 인접한 CDATA 섹션에 넣을 수 있습니다.
전의:
<![CDATA[Certain tokens like ]]> can be difficult and <invalid>]]>
로 작성해야합니다
<![CDATA[Certain tokens like ]]]]><![CDATA[> can be difficult and <valid>]]>
은닉하려면 데이터를 여러 조각으로 나눠야합니다 ]]>
.
모든 것이 여기 있습니다 :
<![CDATA[]]]]><![CDATA[>]]>
첫 번째 <![CDATA[]]]]>
는 ]]
입니다. 두 번째 <![CDATA[>]]>
는 >
입니다.
당신은 이스케이프하지 않지만 , 앞에 삽입 ]]>
하여 >
after 를 피하십시오. 이것은 C / Java / PHP / Perl 문자열과 같지만 a 전후에만 필요 합니다 .]]
]]><![CDATA[
>
\
>
]]
BTW,
S.Lott의 대답은 이것과 동일합니다.
S. Lott의 대답은 맞습니다. 종료 태그를 인코딩하지 않고 여러 CDATA 섹션에서 분리합니다.
실제 환경에서이 문제를 해결하는 방법 : XML 편집기를 사용하여 컨텐츠 관리 시스템에 제공 할 XML 문서를 작성하려면 CDATA 섹션에 대한 기사를 작성하십시오. CDATA 섹션에 코드 샘플을 포함시키는 일반적인 트릭은 여기서 실패합니다. 내가 이것을 어떻게 배웠는지 상상할 수 있습니다.
그러나 대부분의 상황에서이 문제가 발생하지 않는 이유는 다음과 같습니다. XML 문서의 텍스트를 XML 요소의 내용으로 저장하려는 경우 DOM 메소드를 사용합니다. 예를 들면 다음과 같습니다.
XmlElement elm = doc.CreateElement("foo");
elm.InnerText = "<[CDATA[[Is this a problem?]]>";
그리고 DOM은 상당히 합리적으로 <와>를 이스케이프하므로 문서에 CDATA 섹션을 실수로 포함시키지 않았습니다.
아, 그리고 이것은 흥미 롭습니다 :
XmlDocument doc = new XmlDocument();
XmlElement elm = doc.CreateElement("doc");
doc.AppendChild(elm);
string data = "<![[CDATA[This is an embedded CDATA section]]>";
XmlCDataSection cdata = doc.CreateCDataSection(data);
elm.AppendChild(cdata);
This is probably an ideosyncrasy of the .NET DOM, but that doesn't throw an exception. The exception gets thrown here:
Console.Write(doc.OuterXml);
I'd guess that what's happening under the hood is that the XmlDocument is using an XmlWriter produce its output, and the XmlWriter checks for well-formedness as it writes.
simply replace ]]>
with ]]]]><![CDATA[>
Here's another case in which ]]>
needs to be escaped. Suppose we need to save a perfectly valid HTML document inside a CDATA block of an XML document and the HTML source happens to have it's own CDATA block. For example:
<htmlSource><![CDATA[
... html ...
<script type="text/javascript">
/* <![CDATA[ */
-- some working javascript --
/* ]]> */
</script>
... html ...
]]></htmlSource>
the commented CDATA suffix needs to be changed to:
/* ]]]]><![CDATA[> *//
since an XML parser isn't going to know how to handle javascript comment blocks
In PHP: '<![CDATA['.implode(explode(']]>', $string), ']]]]><![CDATA[>').']]>'
A cleaner way in PHP:
function safeCData($string)
{
return '<![CDATA[' . str_replace(']]>', ']]]]><![CDATA[>', $string) . ']]>';
}
Don't forget to use a multibyte-safe str_replace if required (non latin1 $string
):
function mb_str_replace($search, $replace, $subject, &$count = 0)
{
if (!is_array($subject))
{
$searches = is_array($search) ? array_values($search) : array ($search);
$replacements = is_array($replace) ? array_values($replace) : array ($replace);
$replacements = array_pad($replacements, count($searches), '');
foreach ($searches as $key => $search)
{
$parts = mb_split(preg_quote($search), $subject);
$count += count($parts) - 1;
$subject = implode($replacements[$key], $parts);
}
}
else
{
foreach ($subject as $key => $value)
{
$subject[$key] = mb_str_replace($search, $replace, $value, $count);
}
}
return $subject;
}
Another solution is to replace ]]>
by ]]]><![CDATA[]>
.
See this structure:
<![CDATA[
<![CDATA[
<div>Hello World</div>
]]]]><![CDATA[>
]]>
For the inner CDATA tag(s) you must close with ]]]]><![CDATA[>
instead of ]]>
. Simple as that.
참고URL : https://stackoverflow.com/questions/223652/is-there-a-way-to-escape-a-cdata-end-token-in-xml
'IT story' 카테고리의 다른 글
document.write를 포함 할 수있는 src로 스크립트 태그를 동적으로 추가 (0) | 2020.07.07 |
---|---|
지원 라이브러리가있는 FloatingActionButton 예제 (0) | 2020.07.07 |
팬더 데이터 프레임에서 행의 하위 집합 수정 (0) | 2020.07.07 |
PHP에서 두 문자열을 결합하는 방법은 무엇입니까? (0) | 2020.07.07 |
VirtualBox 하드 디스크를 등록 할 수 없습니다 이미 존재합니다 (0) | 2020.07.07 |