XML을 다루다 보면 노드를 통으로 복사하거나 옮겨야 할 때가 있습니다.
닷넷에서는 그런 동작을 할 때 'ImportNode'를 사용합니다.
(참고 : MSDN - ImportNode )
이전 글에서 처럼 테스트 데이터를 도큐먼트로 생성하여 사용합니다.
<?xml version="1.0" encoding="utf-8"?>
<tests>
<test>
<a1>1-0</a1>
<a2>2-0</a2>
<a3>3-0</a3>
</test>
<test>
<a1>1-1</a1>
<a3>3-1</a3>
</test>
<test>
<a1>1-2</a1>
<a2>2-2</a2>
<a3>3-2</a3>
</test>
</tests>
노드(Node)를 복사하기 위해서는
1) 복사하려는 노드를 찾는다.
2) 'ImportNode'로 해당 로드를 복사한다.
3) 대상에 복사된 노드를 추가시킨다.
이런 순서로 하게 됩니다.
//도큐 생성
XmlDocument xDocOriginal = new XmlDocument();
xDocOriginal.LoadXml(sDataOriginal);
XmlDocument xDocTaget = new XmlDocument();
xDocTaget.LoadXml(sDataTaget);
//루트가져오기
XmlNode xNode = xDocOriginal.SelectSingleNode("tests");
//검색할 요소 리스트
XmlNodeList xNodeList = xNode.SelectNodes("test");
//1. 복사하려는 노드를 찾는다. - xNodeList[0]
//2. ImportNode로 해당 로드를 복사한다. - xDocTaget.ImportNode
//3. 복사된 노드를 추가시킨다. - xDocTaget.DocumentElement.AppendChild
xDocTaget.DocumentElement.AppendChild(xDocTaget.ImportNode(xNodeList[0], true));
//출력
textBox1.Text = xDocTaget.OuterXml.ToString();
16번 줄 : 'xNodeList[0]'가 복사할 원본입니다.
'xDocTaget.ImportNode'를 하여 복사할 대상을 넣습니다.
('ImportNode'에 들어가는 옵션은 하위노드를 포함할지 말지 여부입니다.)
'xDocTaget.DocumentElement.AppendChild'를 이용하여 복사할 대상을 넣습니다.
그런데 재미있는 것은 'xDocTaget.ImportNode(xNodeList[0], true)'으로 나오는 내용물입니다.
내용물은 'xNodeList[0]'와 같습니다.
하지만 출력되는 내용만 같을 뿐이지 전혀 다른 객체입니다.
xNodeList[0]를 직접 다른 노드에 추가시키면 이미 다른 컨탠츠에 소속되있다는 에러가 나오게 됩니다.
이것으로 'ImportNode'가 노드'객체를 새로 만들어서 리턴한다는 것을 알 수 있죠.
위 코드를 그대로 실행하면 추가되는 노드는 루트에 추가 됩니다.
더 하위에 추가하려면 어떻게 해야 할까요?
타겟을 차일드 다른 노드로 지정해주시면 됩니다.
예
xDocTaget.ChildNodes[1].AppendChild(xDocTaget.ImportNode(xNodeList[0], true));
'ImportNode'의 결과는 'XmlNode'이기 때문에 'ImportNode'이후 동작은 일반적인 'XML'컨트롤과 똑같습니다.
단지 '루트 요소'인경우 0번 위치가 인트로기때문에 사용할 수 없다는걸 조심해야 하죠 ㅎㅎㅎ
샘플 :
여기까지 따라왔으면 .NET에서 XML 다루는 건 거의 다 할 줄 안다고 보셔도 됩니다.
ㅎㅎㅎ