2010-02-12 3 views
2

dom4j를 사용하여 XML 파일을 읽었습니다. 이 파일은 다음과 같습니다SAXReader가 ecape 문자를 다시 사용하지 않습니다.

... 
<Field>&#13;&#10; hello, world...</Field> 
... 

가 나는 DocumentSAXReader으로 파일을 읽습니다.

\r\n hello, world... 

내가 어떤 처리를 할 다음 asXml()를 사용하여 다른 파일을 작성 : 나는 노드에서 getText()을 사용하면 내가 따라와 문자열을 구하십시오. 그러나 원래 파일에서와 같이 문자를 이스케이프 처리하지 않으므로 파일을 사용하는 외부 시스템에서 오류가 발생합니다.

특수 문자를 이스케이프 처리하고 파일을 쓸 때 &#13;&#10;을 어떻게 가질 수 있습니까?

+0

문자열에 리터럴 개행 문자가 있거나 문자열에 "\ r \ n"이 오는 것을 의미합니까 (예 : 문자?) –

+0

개행 문자가 표시됩니다. 하지만 문제가되지 않습니다. 문자를 얻으려고합니다. ' ' – woezelmann

+0

왜 ' '으로 유지 하시겠습니까? XML을 통해 무엇을 얻으려고합니까? – ewernli

답변

1

쉽게 할 수 없습니다. 그것들은 '도피'가 아니며 '문자 엔티티'입니다. 그것들은 XML의 기본적인 부분입니다. Xerces는 '해석되지 않은 엔티티'에 대해 매우 복잡한 지원을하고 있지만, DTD에 정의 된 종과는 달리 이것들에 적용될 수 있을지는 의문입니다.

+0

좋아요, 그래서 새 줄을 쓸 때 newline을 어떻게 ' '으로 탈출시키는 지 알 것입니다? org.dom4j.Document.asXml()을 사용하고 있습니다. – woezelmann

+0

Xml을 사후 처리 만합니다. 나는 Dom4j에서 매우 녹슬다. – bmargulies

1

그것은에 따라 무엇을 얻고 무엇을 당신이 (내 이전 코멘트를 참조하십시오.)

검출 된 SAX 판독기가 잘못 아무것도하지 않고있다합니다 - 당신의 XML은 당신에게 문자 개행 문자를주고있다. 이 XML을 제어하는 ​​경우 줄 바꿈 문자 대신 "r"또는 "n"문자 다음에 \ (백 슬래시) 문자를 삽입해야합니다.

제어하지 않으면 XML을 사용하면 문자열을 되찾은 후에 개행 문자를 "\ r \ n"로 문자 변환해야합니다. C#에서는 다음과 같이됩니다.

myString = myString.Replace("\r\n", "\\r\\n"); 
+0

제 문제는 ' '이 포함 된 xml 파일을 읽었으며 일부 변환을 수행하고 새 xml 파일을 작성하는 것입니다. 그리고이 새로운 xml 파일에서 ' '을 다시 보내고 싶습니다. 나는 "\ r \ n"이나 "\\ r \\ n"과 같은 것을 원하지 않는다. – woezelmann

+0

그럼 왜 그때 그들을 도망 칠 까 걱정하지 않니? Xerces (실제로 C++ 버전에서)는 실제 문자 그대로의 개행 문자를 인코딩하면 이전 버전과 마찬가지로 나옵니다. 다시 인코딩하기 전에 이스케이프 처리하면 대신 XML에 "\ r \ n"문자가 표시됩니다. C#의 이중 백 슬래시가 문자열의 단일 백 슬래시로 표시됩니다. 그것을 컴파일러에게 이스케이프 시퀀스로 취급하지 말라고 말하는 방법입니다. –

1

XML 엔티티는 DOM에서 추상화되어 있습니다. 대부분의 경우 원하는대로 인코딩에 신경 쓰지 않아도 String을 통해 내용이 노출됩니다.

그러나 SAX는 엔티티 처리 방법에 대한 지원을 일부 제공합니다. 사용자 정의 EntityResolver#resolveEntity을 사용하여 XMLReader을 만들고이를 매개 변수로 SAXReader에 전달할 수 있습니다. 하지만 재주가 작동하지 않을 수 있습니다

파서가 외부 DTD 부분 집합을 포함하는 톱 레벨의 문서 엔티티 (를 제외한 모든 외부 엔티티 를 열기 전에이 방법 를 호출, 외부 엔티티는 는 DTD 내에서 참조 엔티티가 발견 될 때

그렇지 않으면 당신이 방법으로 SAX에 대한 LexicalHandler를 구성을 시도 할 수 있습니다 문서 요소 내에서 참조 및 외부 기관 )를 통지한다. LexicalHandler#startEntity에 대한 자바 독은 말한다 :

보고서 일부 내부 및 외부의 XML 엔티티의 시작입니다.

해결 방법을 변경할 수는 있지만 여전히 도움이 될 수 있습니다.

편집 읽고 DOM4J에서 제공하는 SAXReaderXMLWriter와 XML을 작성해야합니다. reading a XML filewriting an XML file을 참조하십시오. asXml()을 사용하지 말고 직접 파일을 덤프하십시오.

+0

Ok 나는 나의 질문을 편집했는데, 어쩌면 당신이 이것을하는 법을 아는 것, 그것은 또한 나의 문제를 해결할 것이다. – woezelmann

0

입력 스트림을 사전 처리하여 &을 다음과 같이 바꿀 수 있습니다. [$AMPERSAND_CHARACTER$], dom4j를 사용하여 작업을 수행하고 출력 스트림을 후행으로 대체합니다. (streamflyer 사용)

예 :

import com.github.rwitzel.streamflyer.util.ModifyingReaderFactory; 
import com.github.rwitzel.streamflyer.util.ModifyingWriterFactory; 

// Pre-process 
Reader originalReader = new InputStreamReader(myInputStream, "utf-8"); 
Reader modifyingReader = new ModifyingReaderFactory().createRegexModifyingReader(originalReader, "&", "[\\$AMPERSAND_CHARACTER\\$]"); 

// Read and modify XML via dom4j 
SAXReader xmlReader = new SAXReader(); 
Document xmlDocument = xmlReader.read(modifyingReader); 
// ... 

// Post-process 
Writer originalWriter = new OutputStreamWriter(myOutputStream, "utf-8"); 
Writer modifyingWriter = new ModifyingWriterFactory().createRegexModifyingWriter(originalWriter, "\\[\\$AMPERSAND_CHARACTER\\$\\]", "&"); 

// Write to output stream 
OutputFormat xmlOutputFormat = OutputFormat.createPrettyPrint(); 
XMLWriter xmlWriter = new XMLWriter(modifyingWriter, xmlOutputFormat); 
xmlWriter.write(xmlDocument); 
xmlWriter.close(); 

또한 사전 및 사후 처리를 위해/FilterOutputStreamFilterInputStream, PipedInputStream/PipedOutputStream, 또는 ProxyInputStream/ProxyOutputStream 사용할 수 있습니다.