Microsoft MVP성태의 닷넷 이야기
글쓴 사람
정성태 (techsharer at outlook.com)
홈페이지
첨부 파일

원본 파일의 공백/라인을 유지한 체 XML 파일을 저장하는 방법

아는 분과 이야기를 하다가, 그분은 XML 파일로 설정 저장을 하는 것이 싫어서 "Key=Value" 형식의 포맷으로 저장하는 간단한 라이브러리를 사용한다고 하십니다. ^^ XML이 싫은 이유인 즉, 저장하면서 기존 파일에 있던 공백/라인 형식이 모두 제거되고 다시 정렬되기 때문이라고 했습니다.

아하~~~ 아직도 모르고 계셨군요. ^^




예를 들어, 다음과 같은 문서를 로드한 경우,

<?xml version="1.0" encoding="utf-8" ?>

<configure>

    <myParam>1</myParam>

</configure>

XmlDocument로 Load/Save를 하면 기본적으로는 다음과 같이 저장됩니다.

<?xml version="1.0" encoding="utf-8"?>
<configure>
  <myParam>5</myParam>
</configure>

사용자가 멋있게(?) 포맷팅해 둔 텍스트 파일의 형식이 날아가 버린 것입니다. 이를 방지하려면 다음과 같이 Load 이전에 PreserveWhitespace = true 설정을 해주시면 됩니다.

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.PreserveWhitespace = true;
xmlDoc.Load("test.xml");

이렇게 로드된 파일을 저장하면 다음과 같이 서식(?)이 유지된답니다. ^^

<?xml version="1.0" encoding="utf-8" ?>

<configure>

    <myParam>5</myParam>

</configure>

재미있는 것은 PreserveWhitespace가 Load 이전에 설정했을 때와 Save 이전에 설정했을 때가 동작 방식이 다르다는 점입니다.

XmlDocument.PreserveWhitespace Property 
; https://docs.microsoft.com/en-us/dotnet/api/system.xml.xmldocument.preservewhitespace

If PreserveWhitespace is true before Save is called, white space in the document is preserved in the output; otherwise, if this property is false, XmlDocument auto-indents the output.


더욱 재미있는 점은, 위의 문서 내용과는 다르게 다음과 같이 Save 이전에 값을 true로 설정해 주면 아예 공백 문자들이 모두 날아간 최적화된(?) 문자열을 반환한다는 것입니다.

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load("test.xml");

xmlDoc.PreserveWhitespace = true;
xmlDoc.Save(Console.Out);

// 출력 결과:
<?xml version="1.0" encoding="utf-8"?><configure><myParam>5</myParam></configure>

이렇게 해서 공백을 아예 제거하는 방법과, 사용자의 원본 서식을 유지하는 방법을 알아봤는데요. 그렇다면 '들여쓰기'를 정규화시켜서 출력을 해주고 싶다면 어떻게 해야 할까요? 그럴 때는 다음과 같이 XmlWriterSettings 옵션을 사용하시면 됩니다. ^^

XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true;
settings.IndentChars = "    "; //  4개의 공백 문자
settings.NewLineChars = Environment.NewLine;
settings.NewLineHandling = NewLineHandling.Replace;

XmlWriter writer = XmlWriter.Create(Console.Out, settings);
xmlDoc.Save(writer);

그럼, 출력 결과는 다음과 같이 네모반듯(?)하게 나옵니다. ^^

<?xml version="1.0" encoding="ks_c_5601-1987"?>
<configure>
    <myParam>5</myParam>
</configure>

이 정도 자유롭게 출력할 수 있으니... XML 사용에 주저하지 마시길 바랍니다. ^^

(첨부된 파일은 위의 코드를 포함한 예제 프로젝트입니다.)




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]







[최초 등록일: ]
[최종 수정일: 7/17/2021]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 



2012-03-06 01시04분
[지송] 좋은 팁 얻어갑니다. 따뜻한 봄 맞이하세요.
[guest]

... 16  17  18  19  20  21  22  [23]  24  25  26  27  28  29  30  ...
NoWriterDateCnt.TitleFile(s)
13399정성태8/9/202311591닷넷: 2135. C# - 지역 변수로 이해하는 메서드 매개변수의 값/참조 전달
13398정성태8/3/202314905스크립트: 55. 파이썬 - pyodbc를 이용한 SQL Server 연결 사용법
13397정성태7/23/202314030닷넷: 2134. C# - 문자열 연결 시 string.Create를 이용한 GC 할당 최소화
13396정성태7/22/202313491스크립트: 54. 파이썬 pystack 소개 - 메모리 덤프로부터 콜 스택 열거
13395정성태7/20/202312603개발 환경 구성: 685. 로컬에서 개발 중인 ASP.NET Core/5+ 웹 사이트에 대해 localhost 이외의 호스트 이름으로 접근하는 방법
13394정성태7/16/202311329오류 유형: 873. Oracle.ManagedDataAccess.Client - 쿼리 수행 시 System.InvalidOperationException
13393정성태7/16/202312337닷넷: 2133. C# - Oracle 데이터베이스의 Sleep 쿼리 실행하는 방법
13392정성태7/16/202311731오류 유형: 872. Oracle - ORA-01031: insufficient privileges
13391정성태7/14/202312148닷넷: 2132. C# - sealed 클래스의 메서드를 callback 호출했을 때 인라인 처리가 될까요?
13390정성태7/12/202312475스크립트: 53. 파이썬 - localhost 호출 시의 hang 현상
13389정성태7/5/202313002개발 환경 구성: 684. IIS Express로 호스팅하는 웹을 WSL 환경에서 접근하는 방법
13388정성태7/3/202313459오류 유형: 871. 윈도우 탐색기에서 열리지 않는 zip 파일 - The Compressed (zipped) Folder '[...].zip' is invalid. [1]파일 다운로드1
13387정성태6/28/202312016오류 유형: 870. _mysql - Commands out of sync; you can't run this command now
13386정성태6/27/202313420Linux: 61. docker - 원격 제어를 위한 TCP 바인딩 추가
13385정성태6/27/202312675Linux: 60. Linux - 외부에서의 접속을 허용하기 위한 TCP 포트 여는 방법
13384정성태6/26/202312155.NET Framework: 2131. C# - Source Generator로 해결하는 enum 박싱 문제파일 다운로드1
13383정성태6/26/202312474개발 환경 구성: 683. GPU 런타임을 사용하는 Colab 노트북 설정
13382정성태6/25/202311649.NET Framework: 2130. C# - Win32 API를 이용한 윈도우 계정 정보 (예: 마지막 로그온 시간)파일 다운로드1
13381정성태6/25/202312724오류 유형: 869. Fatal Python error: init_fs_encoding: failed to get the Python codec of the filesystem encoding
13380정성태6/24/202311203스크립트: 52. 파이썬 3.x에서의 동적 함수 추가
13379정성태6/23/202311823스크립트: 51. 파이썬 2.x에서의 동적 함수 추가
13378정성태6/22/202312472오류 유형: 868. docker - build 시 "CANCELED ..." 뜨는 문제
13377정성태6/22/202317463오류 유형: 867. 파이썬 mysqlclient 2.2.x 설치 시 "Specify MYSQLCLIENT_CFLAGS and MYSQLCLIENT_LDFLAGS env vars manually" 오류
13376정성태6/21/202313245.NET Framework: 2129. C# - Polly를 이용한 클라이언트 측의 요청 재시도파일 다운로드1
13375정성태6/20/202311641스크립트: 50. Transformers (신경망 언어모델 라이브러리) 강좌 - 2장 코드 실행 결과
13374정성태6/20/202311258오류 유형: 866. 파이썬 - <class 'AttributeError'> module 'flask.json' has no attribute 'JSONEncoder'
... 16  17  18  19  20  21  22  [23]  24  25  26  27  28  29  30  ...