khstar

Xpath 본문

BEA/ALSB

Xpath

khstar 2008. 1. 3. 19:46
반응형
 

5. XPath 쿼리

  지금은 약 1년 전에 제가 썼던 강좌를 약간 고쳐서 올려놓고 있습니다. 빨랑 이전 강좌를 올리고 따근따근한 새 강좌를 진행하도록 하겠습니다. 만약 궁금한 내용이나 새롭게 원하는 강좌가 있으면 메일 주시고요.. 궁금한 사항은 Q&A 게시판을 이용해 주시기 바랍니다.



그럼 오늘은 지난번 XDR 스키마에서 약간 언급한 적이 있는 XPath에 대해서 좀더 알아보려구 합니다.

굳이 MSSQL에서가 아니더라도 여러분이 XML을 하다보면 XPath를 사용해야 하는 경우가 많이 있을 겁니다.



XPath는 XML 문서 내에서 검색 방법을 제시해 주는 것이니까요.. 중요합니다.

제 경우 처음에 XQL 과 XML-QL이라는 두가지 XML  쿼리를 공부했었습니다.



그리고 난 후에 XPath라는 것이 나왔더군요..

그래서 잉 이 생소한 것을 어떻게 또 공부해야 하나?? 하고 고민했었습니다.



그러나 다행히도 XQL과 큰 차이가 없더라구요.. 이둘의 관계가 있긴 할 것인데.. 제가 아직 미처 확인하지 못했습니다.

나중에 확인되면 다시 언급하죠.. 혹 아시는 분은 제게 알려주시면 고맙구요..



오늘도 여전히 서두가 길었습니다. 자.. 그럼 시작해 보도록 하죠..



XPath 쿼리 사용



XPath의 사용 예를 먼저 살펴보죠..



/child::Customer[attribute::CustomerID="ALFKI"]



여기에서 child는 자식을 나타내는 키워드이고 attribute는 속성을 나타내는 키워드입니다.

그리고 []는 보통 필터라고 한다고 하였죠.. 즉, 조건을 나타냅니다.



그럼.. 속성 CustomerID가 "ALFKI"인 <Customer>엘리먼트를 찾아라... 가 됩니다.

맞나요???



이걸 일반적인 형태로 변환하면 다음처럼 사용하셔도 같은 내용입니다.



/Customer[@CustomerID="ALFKI"]



child::는 기본값으로 인식되구요.. attribute::는 @로 단축시켜서 표현이 가능합니다.



또다른 예를 하나 볼까요??



/child::Customer/child::Order[attribute::OrderID="1"]



단축형으로 표현해 보면



/Customer/Order[@OrderID="1"]



이것은 어떻게 해석할 수 있을까요?? 한번 해보세요..



<Customer>엘리먼트의 자식 엘리먼트인 <Order>엘리먼트를 찾는데 그 속성 OrderID가 1인 것만 찾아라...



자!! 어떻게 느낌이 오나요??



/A/B 의 경우는 <B> 엘리먼트가 반환됩니다. 그러나

/A[B]의 경우는 <B>를 포함하고 있는 <A>엘리먼트가 반환됩니다.



이 차이를  XPath에서는 잘 이해하셔야 합니다.



예제를 계속 보도록 하죠.. 지금부터는 단축형으로 사용합니다.



/Customer[ContactName]



<ContactName> 엘리먼트를 자식으로 가지고 있는 <Customer>엘리먼트를 찾아라..



/Customer[not(ContactName)]



엉.. not() 함수가 사용되었습니다. 위의 것과 반대가 되겠죠..



<ContactName> 엘리먼트를 자식으로 가지고 있지 않은 <Customer>엘리먼트를 찾아라..



/Customer[@CustomerID]



속성 CustomerID를 가지고 있는 <Customer>엘리먼트를 찾아라..



이런 식으로 나타낼 수 있습니다. 쉽죠... 이부분은 아마 제가 MSSQL 강의하는 부분들 중에서 가장 쉽게 받아들일 수 있을 겁니다.

기존에 우리가 사용하던 방식과 별 차이가 없기 때문이죠...



그래도.. 우리가 또 결과를 직접 보면서 해보는 게 중요하지 않을런지요.. 그래서 Books Online에 있는 예제를 가지고 실습해 보도록 하죠..



XPath를 사용하기 위해서는 먼저 XDR 스키마를 선언할 필요가 있습니다.

그래서 예제로 나와있는 XDR 스키마를 사용하도록 하겠습니다.  이 소스를 보면 기가찹니다.. 넘 길어서... ~~

그래도 지난 번에 배운걸 토대로 아는 것만이라도 봐두세요.. 반드시..


이 예제를 모두 본인 PC에서 테스트 하시려면 자료모음에서 해당 소스파일을 받아서 Template 디렉토리에 복사하세요.

 

기본 XPath 쿼리



1. 자식 엘리먼트를 검색하는 예제입니다.



/Employee



파일명 : Xpath1.xml

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">

    <sql:xpath-query mapping-schema="XpathSchema.xml">

            /Employee

    </sql:xpath-query>

</ROOT>





위와 같이 템플릿을 만들고 다음처럼 실행하면 됩니다.

http://localhost/mini/template/Xpath1.xml



2. 손자 엘리먼트를 검색하는 예제입니다.



/Customer/Order



파일명 : Xpath2.xml

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">

    <sql:xpath-query mapping-schema="XpathSchema.xml">

            /Customer/Order

    </sql:xpath-query>

</ROOT>





실행하면...

http://localhost/mini/template/Xpath2.xml



이렇게 하면 <Order>엘리먼트가 리턴됩니다..



3. CustomerID의 속성값이 "ALFKI"인 <Customer> 엘리먼트를 검색하는 예제입니다.



/Customer[@CustomerID="ALFKI"]



파일명 : Xpath3.xml

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">

    <sql:xpath-query mapping-schema="XpathSchema.xml">

            /Customer[@CustomerID="ALFKI"]

    </sql:xpath-query>

</ROOT>





또 실행해 볼까여??

http://localhost/mini/template/Xpath3.xml



그러면 ALFKI의 <Cusotmer>엘리먼트만이 나타납니다....



이상으로 위에서 설명한 기본 XPath 쿼리를 사용해 보았습니다.

이제부터는 조금 복잡한 것을 한번 사용해 보도록 하죠.. XPath를 눈에 익혀 보세요.. ^^;;



조건 지정 XPath 쿼리



1. 여러개의 조건 지정



/Customer[@CustomerID="ALFKI"]/Order[@OrderID="Ord-10643"]



파일명 : Xpath4.xml

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">

    <sql:xpath-query mapping-schema="XpathSchema.xml">

            /Customer[@CustomerID="ALFKI"]/Order[@OrderID="Ord-10643"]

    </sql:xpath-query>

</ROOT>





이 경우는 쿼리가 상당히 복잡합니다.

그러나 차근 차근 해석해 보면 어렵지 않네요.. 일단 조건을 제외하면 /Customer/Order입니다.



즉, <Order>엘리먼트가 리턴됩니다.

그리고 조건을 보면 속성 CustomerID가 "ALFKI"인 <Customer>중에서 OrderID가 "Ord-10643"인 <Order>를 찾는 겁니다.

이해가 되죠.... 잘 보셔요... 함 실행해보죠.. 정말 그것이 리턴되었는지..



http://localhost/mini/template/Xpath4.xml



결과를 보면 OrderID가 "Ord-10643"인 <Order>라 리턴이 되었죠.. 물론 이것은 <Customer>의 자식이구요..



2. 연속 조건 지정



/Customer[@City="London"][@Fax]



파일명 : Xpath5.xml

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">

    <sql:xpath-query mapping-schema="XpathSchema.xml">

            /Customer[@City="London"][@Fax]

    </sql:xpath-query>

</ROOT>





갈수록 소스가 이상해집니다.. 헐~~~



자 이 경우에 반환되는 결과 엘리먼트는 무엇일까요?? 당근... <Customer>입니다.

조건을 보면요?? 속성 City가 "London"이어야 합니다. 그다음에 또 조건이 있습니다.

[@Fax]는 무엇이냐하면요.. Fax라는 속성의 값을 가지고 있어야 한다는 것입니다.



즉, City가 "London"이고 Fax란 속성을 포함하고 있는 <Customer>엘리먼트를 리턴하는 겁니다.

결과를 보죠...



http://localhost/mini/template/Xpath5.xml



조건을 만족하는 고객이 5명이 있군요.. 그쵸..



이제 각종 연산자나 함수를  XPath에 지정하는 예를 살펴 보겠습니다.



연산자나 함수를 사용하는 XPath 쿼리



1. 관계 연산자 적용



/Customer[Order/OrderDetail[@Quantity>5]]



이걸 템플릿에 적용하려면 >를 태그로 해석하지 않게 하기 위해서 >로 변환해 주어야 합니다.



파일명 : Xpath6.xml

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">

    <sql:xpath-query mapping-schema="XpathSchema.xml">

            /Customer[Order/OrderDetail[@Quantity > 5]]

    </sql:xpath-query>

</ROOT>





여기에서 <Customer>, <Order>, <OrderDetail>의 세가지 엘리먼트가 나옵니다.

결과로 리턴되는 엘리먼트는 무엇일까요??



답은 <OrderDetail>입니다. 그쵸.. 퍽~~~~졸지 마세요.....



<Customer> 엘리먼트가 리턴된다고 했습니다. []는 조건이고 그 앞의 것이 반환된다고 했었죠..



그리고 저는 템플릿에서 >로 인코딩해서 사용했습니다. 근데 인코딩을 하지 않아도 결과가 나옵니다.

그러나 원칙은 인코딩해주어야 합니다.



결과를 보죠..

http://localhost/mini/template/Xpath6.xml



2. 산술 연산자 적용



/OrderDetail[@UnitPrice * @Quantity = 98]



파일명 : Xpath7.xml

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">

    <sql:xpath-query mapping-schema="XpathSchema.xml">

            /OrderDetail[@UnitPrice * @Quantity = 98]

    </sql:xpath-query>

</ROOT>





이것은 UnitPrice 속성과 Quantity 속성의 곱이 98인 <OrderDetail> 엘리먼트가 리턴됩니다.



http://localhost/mini/template/Xpath7.xml



어때요.. 계속 해보니 감이 팍팍 오죠....  두어개만 더 해보죠..



3. 형 변환 함수 적용



/Employee[number(@EmployeeID)=4]



파일명 : Xpath8.xml

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">

    <sql:xpath-query mapping-schema="XpathSchema.xml">

            /Employee[number(@EmployeeID)=4]

    </sql:xpath-query>

</ROOT>





number()란 함수가 사용되었네요.. 숫자로 바꾸라는 것같죠..



http://localhost/mini/template/Xpath8.xml



만약 문자열로 변환하고자 할 경우에는 string()을 사용하면 됩니다.



4. BOOL 연산자 적용



/Customer[@CustomerID="ALFKI" or @CustomerID="ANATR"]



파일명 : Xpath9.xml

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">

    <sql:xpath-query mapping-schema="XpathSchema.xml">

           /Customer[@CustomerID="ALFKI" or @CustomerID="ANATR"]

    </sql:xpath-query>

</ROOT>





중간에 or 연산자가 사용되었습니다. 두 개의 <Customer>엘리먼트가 반환됩니다.



http://localhost/mini/template/Xpath9.xml





/Customer[not(Order)]



파일명 : Xpath10.xml

<ROOT xmlns:sql="urn:schemas-microsoft-com:xml-sql">

    <sql:xpath-query mapping-schema="XpathSchema.xml">

           /Customer[not(Order)]

    </sql:xpath-query>

</ROOT>





이 경우에는 <Order>엘리먼트를 포함하지 않은 <Customer>엘리먼트를 리턴합니다.

결과를 볼까요??



http://localhost/mini/template/Xpath10.xml



이 경우 다음과 같이 XPath를 바꾸어도 같은 결과를 반환합니다.



/Customer[Order=false()]



휴~~ 이렇게 많은 XPath 쿼리에 대해서 알아보았습니다. 여기에 물론 템플릿 실행에서 배웠던 매개변수도 적용할 수 있습니다.

그건 한번씩 찾아 보시길 바라구요...



XPath는 XML에 있어서 중요한 위치를 차지하고 있습니다. 설사 MSSQL에 관심이 없다 하더라도 잘 읽어 보시기 바랍니다


출처 : 뿌로그래머(cafe.naver.com/inline8949ok) - 프랜드(nnnok1)

반응형
Comments