XML로 만들어진 여러 마크업언어를 혼합하여 사용할 수 있는데, 그럴 경우 발생하는 문제가 바로 엘리먼트 이름의 충돌이다. 흔히 이런 류의 문제는 네임스페이스라는 것을 선언해서 해결하게된다.
- xml에서 네임스페이스는 URI(Uniform Resource Identifier)형태로 제작된다. URI형태로 제작하는 것이, 기존의 네임스페이스와 새로 정의될 네임스페이스의 충돌을 최소화할 수 있기 때문이다.
- xml로 제작된 각 마크업언어는 하나의 네임스페이스를 가질 수 있다. (물론 가지지않을 수 도 있다.)
- XML Schema를 이용해서 마크업언어를 작성할 경우, 네임스페이스 값은 어떻게 할 것이며 네임스페이스를 반드시 선언해야하는냐 등을 정의 할 수 있는 문법을 제공한다. Schema에서 네임스페이스를 반드시 사용하도록 지정했다면, xml문서에서 해당 네임스페이스를 선언하고 사용해야한다.
네임스페이스 선언
- 네임스페이스를 사용하도록 만들어졌다면, 각 엘리먼트의 접두사로 네임스페이스 명이 사용되어야한다. 하지만 URI형태로 제작된 네임스페이스를 필요할 때마다 사용하는 것은 비효율적이다. 그리고 네임스페이스 값 자체가, xml에서 사용하기 곤란한 문자들을 다수 포함하기에, 네임스페이스를 대신하는 별칭을 선언하여 사용하게 된다.
<!--네임스페이스 선언--> <접두사:엘리먼트명 xmlns:접두사="네임스페이스명"> <!--네임스페이스 사용--> <접두사:엘리먼트명></접두사:엘리먼트명> |
- 접두사의 작명규칙은 xml의 일반적인 작명규칙과 동일하다.
- '접두사:엘리먼트명'은 QName(Qualified name)라고 하며, XML해석기는 QName을 하나의 엘리먼트명으로 간주하게 된다.
- 네임스페이스를 선언하는 엘리먼트 부터, 그 엘리먼트의 모든 자식 엘리먼트까지 네임스페이스의 적용 범위가 된다.
- 여러 네임스페이스를 선언하는 경우는 다음과 같다. 한가지 알아 둘 점은, 네임스페이스를 선언하는 엘리먼트가 무조건 해당 네임스페이스에 포함되는 엘리먼트가 아니여도 된다는 점이다. 즉, 하나의 루트 엘리먼트에 모든 네임스페이스 선언을 같이 해도 된다는 말이다.(그 루트엘리먼트가 선언하는 네임스페이스와 전혀 상관없더라도 말이다.) 다음 예제를 통해 알아보자.
<!-- 여러 네임스페이스 선언 루트엘리먼트는 A네임스페이스에 속하는 엘리먼트지만, 루트엘리먼트에 다른 모든 네임스페이스를 선언하고있다. 엘리먼트의 선언은 소속에 관계없이 어떤 엘리먼트에서도 가능하지만, 사용은 반드시 소속엘리먼트에만 해야한다. --> <A:루트엘리먼트 xmlns:A="A네임스페이스" xmlns:B="B네임스페이스" xmlns:C="C네임스페이스"> <A:엘리먼트 /> <B:엘리먼트> <B:자식엘리먼트 /> </B:엘리먼트> <C:엘리먼트 /> |
- Default Namespace : 하나의 마크업 언어를 사용할 경우, 굳이 네임스페이스를 위해 접두사를 모두 붙이는 것은 오히려 거추장스럽다. 이를 위해서 Default Namespace를 제공하고 있다.
<!-- Default Namespace는 Namespace선언 시 접두사를 생략하면 된다. --> <엘리먼트명 xmlns="네임스페이스"> <자식엘리먼트 /> </엘리먼트명> |
- Default Namespace를 사용하면, 네임스페이스 범위의 모든 엘리먼트에 네임스페이스가 부여된 상태로 간주되는데, 네임스페이스에 속하지 않는 엘리먼트가 있을 경우나, 부분적으로 다른 네임스페이스에 속하는 엘리먼트가 올 경우 다음과 같은 문법을 사용해야한다.
<!-- Default Namespace선언--> <루트엘리먼트 xmlns="네임스페이스"> <!-- Default Namespace에 속하지 않는 엘리먼트--> <엘리먼트A xmlns="" /> <!-- 다른 Namespace에 속하는 엘리먼트의 경우--> <엘리먼트B xmlns="네임스페이스B" /> </엘리먼트> |
위에서, Default Namespace 범위안에 특정 엘리먼트들은 자신이 다시 네임스페이스를 선언함으로서, Default Namespace의 범위를 벗어났다. 그리고, 당연히 그 자식 엘리먼트들은 부모 엘리먼트의 영향을 받게 된다. - 속성과 Namespace : 속성도 Namespace의 적용을 받으므로, 접두사를 붙여야한다.
- Default Namespace와 속성 : Default Namespace의 범위안에 속성은 Namespace의 적용을 받지 않는다. 따라서, 다음과 같은 방법으로 해결해야한다.
<!-- 같은 네임스페이스 선언을 Default Namespace와 일반 Namespace방법 모두 선언함으로서, 속성이 Default Namesapce에 속하지 않는 문제를 해결한다. 속성은 Default Namespace에 속하지 않으므로, 속성 앞에는 접두사를 사용한다. --> <엘리먼트 xmlns="네임스페이스" xmlns:접두사="네임스페이스"> <자식엘리먼트 접두사:속성="값" /> </엘리먼트> |
- XML Schema를 이용하여 새로운 마크업언어를 작성할 때, 네임스페이스 명과 네임스페이스에 대한 여러 옵션을 다룰 수 있지만, 여기서 그 내용을 기술하지는 않겠다.