Mark Up/XML XML/XPath
  • 728x90
    반응형

    XPath




    XPath란 ?



    XPath란 XML Path Language를 의미한다.

    XPath는 XML 문서의 특정 요소나 속성에 접근하기 위한 경로를 지정하는 언어이다.

    XPath는 W3C 표준 권고안으로, XSLT와 XPointer에 사용될 목적으로 만들어졌다.

    또한, XML DOM에서 노드를 검색할 때에도 사용할 수 있다.


    현재 가장 최신 버전의 XPath는 2017년 3월 17일에 발표된 XPath 3.1이다.

    XPath 3.1에 대한 더 자세한 정보를 원한다면, W3C 공식 사이트를 방문하여 확인할 수 있다.


    https://www.w3.org/TR/xpath-31/



    XPath의 특징



    XPath는 XML 문서의 일부분을 선택하고 처리하기 위해 만들어진 언어이다.

    이러한 XPath는 다음과 같은 특징을 가진다.


    1. XPath는 XML 문서를 탐색하기 위해 경로 표현식(path expression)을 사용한다.
    2. XPath는 수학, 문자열 처리 등을 하기 위한 표준 함수 라이브러리를 내장하고 있다.
    3. XPath는 W3C 표준 권고안인 XSLT에서 가장 중요한 부분 중 하나이다.



    XPath 노드의 형식



    XPath에서 사용하는 노드의 형식은 다음과 같이 구분된다.


    1. 루트 노드
    2. 요소 노드
    3. 텍스트 노드
    4. 속성 노드
    5. 주석 노드
    6. 네임스페이스(namespace)노드
    7. 처리 명령(processing instruction)노드


    XPath 표현식(expression)



    XPath에서는 XML 문서의 노드나 노드셋(node-set)을 선택하기 위해 다양한 표현식을 사용한다.


    아래 예제에서 사용되는 programming_languages.xml 파일의 코드는 다음과 같다.



    Tip : 노드셋(node-set)이란 중복을 허용하지 않는 노드들의 순서없는 집합을 의미한다.



    위치 경로(location path)



    위치 경로(location path)란 XML 문서의 각 노드의 위치를 지정하기 위한 XPath 표현식이다.

    위치 경로는 절대 경로와 상대 경로로 구분할 수 있다.


    • 절대 경로는 슬래시(/)로 시작하며, 루트 노드부터 순서대로 탐색해 나간다.
    • 상대 경로는 슬래시(/)로 시작하지 않으며, 기준으로 지정되는 노드부터 탐색해 나간다.
    위치 경로는 모두 시작 위치 이외에도 슬래시(/)로 구분되어 여러 단계(step)를 포함할 수 있다.

    위치 경로 표현에 사용되는 대표적인 연산자는 다음과 같다.

    경로 연산자

    설명

    노드 이름

    해당 '노드 이름'과 일치하는 모든 노드를 선택함.

    /

    루트 노드부터 순서대로 탐색해 나감.

    //

    현재 노드의 위치와 상관없이 지정된 노드에서부터 순서대로 탐색해 나감.

    .

    현재 노드를 선택함.

    ..

    현재 노드의 부모 노드를 선택함.

    @

    속성 노드를 선택함.


    예제

    developer : <developer> 요소를 모두 선택함.

    /p_languages : 루트 노드의 자식 노드인 <p_languages>요소를 선택함. (절대 경로 탐색)

    p_languages/language : <p_languages> 요소의 자식 노드 중 <language>요소를 모두 선택함. (상대 경로 탐색)

    // : 루트 노드의 하위 노드를 모두 선택함    

    // priority : 위치에 상관없이 <priority> 요소를 모두 선택함.

    .// : 현재 노드의 하위 노드를 모두 선택함.

    version/@status : 모든 <version>요소의 status 속성 노드를 모두 선택함.


    Tip : 위치 경로가 슬래시(/)로 시작하면 언제나 단 하나의 요소만을 가리키는 절대 경로를 나타낸다.


    다음 예제는 위치에 상관없이 <version> 요소를 모두 선택하는 예제이다.


    예제

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    <!DOCTYPE html>
    <html lang="ko">
     
    <head>
        <meta charset="UTF-8">
        <title>XML Xpath</title>
        <script>
            function loadDoc() {
                var xmlHttp = new XMLHttpRequest();
                xmlHttp.onreadystatechange = function() {
                    if(this.status == 200 && this.readyState == this.DONE) {
                        findResult(xmlHttp);
                    }
                };
                xmlHttp.open("GET", "/examples/media/programming_languages.xml", true);
                xmlHttp.send();
            }
     
            function findResult(xmlHttp) {
                var xmlObj, path, result, nodeList, node;
                xmlObj = xmlHttp.responseXML;
                path = "//version";
                result = "";
     
                // 익스플로러를 위한 코드
                if (window.ActiveXObject !== undefined || xmlHttp.responseType == "msxml-document") {
                    xmlObj.setProperty("SelectionLanguage", "XPath");
                    nodeList = xmlObj.selectNodes(path);
     
                    for (i=0; i<nodeList.length; i++) {
                        result +nodeList[i].text + "<br>";
                    }
                // 익스플로러를 제외한 브라우저를 위한 코드
                } else if (document.implementation && document.implementation.createDocument) {
                    nodeList = xmlObj.evaluate(path, xmlObj, null, XPathResult.ANY_TYPE, null);
                    node = nodeList.iterateNext();
                    while (node) {
                        result +node.firstChild.nodeValue + "<br>";
                        node = nodeList.iterateNext();
                    }
                }
                
                document.getElementById("text").innerHTML = result;
            }
        </script>
    </head>
     
    <body>
     
        <h1></h1>
        <button onclick="loadDoc()">경로 표현식 //version 확인!</button>
        <p id="text"></p>
        
    </body>
     
    </html>
    cs



    노드를 찾기 위한 검색 방향 설정



    XPath에서 검색 방향(axis step)은 현재 노드를 기준으로 어느 방향으로 검색해 나갈지를 명시한다.



    XPath에서 사용할 수 있는 검색 방향(axis step)은 다음과 같다.


    검색 방향

    설명

    self

    현재 노드를 선택함.

    attribute

    현재 노드의 속성 노드를 모두 선택함.

    namespace

    현재 노드의 네임스페이스 노드를 모두 선택함.

    child

    현재 노드의 자식 노드를 모두 선택함.

    descendant

    현재 노드의 자손 노드를 모두 선택함.

    descendant-or-self

    현재 노드와 현재 노드의 자손 노드를 모두 선택함.

    following-sibling

    현재 노드 이후에 위치하는 형제 노드를 모두 선택함.

    parent

    현재 노드의 부모 노드를 선택함.

    ancestor

    현재 노드의 조상 노드를 모두 선택함.

    ancestor-or-self

    현재 노드와 현재 노드의 조상 노드를 모두 선택함.

    preceding

    XML 문서에서 현재 노드 이전에 등장하는 모든 노드를 선택함.
    (조상 노드, 속성 노드, 네임스페이스 노드는 제외함) 

    preceding-sibling

    현재 노드 이전에 위치하는 형제 노드를 모두 선택함.



    경로 표현식(path expression)



    XPath에서는 노드를 선택하기 위해 경로 표현식(path expression)을 사용한다.


    XPath에서 경로 표현식을 작성하는 문법은 다음과 같다.


    문법

    검색방향::노드테스트[필터표현식]


    1. 검색 방향 : 현재 노드를 기준으로 노드를 검색할 방향을 전달한다.
    2. 노드 테스트 : 검색 방향에 존재하는 해당 노드를 검색한다.
    3. 필터 표현식 : 검색된 노드셋(node-set)에서 특정 노드나 특정 값을 포함하는 노드를 선택한다.


    예제

    child::language : 현재 노드의 자식 노드 중 <language>요소를 모두 선택함.

    attribute::version : 현재 노드의 version 속성 노드를 선택함.

    descendant:::* : 현재 노드의 자손 노드를 모두 선택함.

    descendant::text( ) : 현재 노드의 자손 노드 중 텍스트 노드를 모두 선택함.

    ancestor::language : 현재 노드의 조상 노드 중 <language>요소를 모두 선택함.

    ancestor-or-self::language : 현재 노드와 현재 노드의 조상 노드 중 <language> 요소를 모두 선택함.

    child::*/child::category : 현재 노드의 자식 노드의 자식 노드 중 <category> 요소를 모두 선택함.


    다음 예제는 현재 노드의 자손 노드를 모두 선택하는 예제이다.


    예제

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    <!DOCTYPE html>
    <html lang="ko">
     
    <head>
        <meta charset="UTF-8">
        <title>XML Xpath</title>
        <script>
            function loadDoc() {
                var xmlHttp = new XMLHttpRequest();
                xmlHttp.onreadystatechange = function() {
                    if(this.status == 200 && this.readyState == this.DONE) {
                        findResult(xmlHttp);
                    }
                };
                xmlHttp.open("GET""/examples/media/programming_languages.xml"true);
                xmlHttp.send();
            }
     
            function findResult(xmlHttp) {
                var xmlObj, path, result, nodeList, node;
                xmlObj = xmlHttp.responseXML;
                path = "descendant::*";
                result = "";
     
                // 익스플로러를 위한 코드
                if (window.ActiveXObject !== undefined || xmlHttp.responseType == "msxml-document") {
                    xmlObj.setProperty("SelectionLanguage""XPath");
                    nodeList = xmlObj.selectNodes(path);
     
                    for (i=0; i<nodeList.length; i++) {
                        result += nodeList[i].text + "<br>";
                    }
                // 익스플로러를 제외한 브라우저를 위한 코드
                } else if (document.implementation && document.implementation.createDocument) {
                    nodeList = xmlObj.evaluate(path, xmlObj, null, XPathResult.ANY_TYPE, null);
                    node = nodeList.iterateNext();
     
                    while (node) {
                        result += node.firstChild.nodeValue + "<br>";
                        node = nodeList.iterateNext();
                    }
                }
                
                document.getElementById("text").innerHTML = result;
            }
       </script>
    </head>
     
    <body>
     
        <h1></h1>
        <button onclick="loadDoc()">경로 표현식 descendant::* 확인!</button>
        <p id="text"></p>
        
    </body>
     
    </html>
    cs



    필터 표현식(filter expressions)



    XPath에서는 특정 노드나 특정 값을 포함하는 노드를 선택하기 위해 필터 표현식(filter expressions)을 사용한다.


    필터 표현식은 언제나 대괄호([])안에 표현된다.

    이러한 필터 표현식에 XPath 함수를 사용하면 더욱 자세한 필터링을 할 수 있다.


    예제

    p_languages/language[1] : <p_languages> 요소의 자식 노드 중 첫 번째 <language> 요소를 선택함.

    p_languages/language[position() < 3] : <p_languages>요소의 자식 노드 중 처음 두 개의 <language>요소를 선택함.

    p_languages/language[last()] : <p_languages>요소의 자식 노드 중 마지막<language>요소를 선택함.

    //priority[@rating] : rating 속성을 가지고 있는 <priority>요소를 모두 선택함.

    //priority[@rating = 3] : rating 속성의 속성값이 3인 <priority>요소를 모두 선택함.

    count(//language) : 모든 <language>요소의 개수를 반환함.



    XPath 함수



    XPath 함수는 선택된 노드셋을 평가하여 조건에 맞는 노드를 시퀀스 형태로 반환한다.


    가장 많이 사용되는 XPath 함수는 다음과 같다.


    XPath 함수

    설명

    position( )

    현재 노드셋 안에서의 노드의 위치를 반환함.

    last( )

    현재 노드셋의 마지막 노드를 반환함.

    count(위치경로)

    지정된 노드셋의 총 노드 개수를 반환함.

    name( )

    현재 노드의 이름을 반환함.

    name(위치경로)

    지정된 노드셋의 첫 번째 노드를 반환함.


    XPath 함수에 대한 더 자세한 정보를 원한다면, W3C 공식 사이트를 방문하여 확인할 수 있다.


    https://www.w3.org/TR/xpath-functions-31/



    임의 문자 기호(wild card)



    XPath에서는 임의의 노드를 선택하기 위해 임의 문자 기호(wild card)를 사용할 수 있다.


    임의 문자 기호

    설명

    *

    어떠한 요소 노드와도 일치함.

    @*

    어떠한 속성 노드와도 일치함.

    node( )

    어떠한 종류의 어떤 노드와도 일치함.

    text( )

    어떠한 텍스트 노드와도 일치함.


    예제

    ../* : 현재 노드의 부모 노드의 자식 요소 노드를 모두 선택함.

    //* : 현재 문서의 모든 요소 노드를 선택함.

    //priority[@*] : 어떠한 종류의 속성 노드라도 적어도 하나 이상 가지고 있는 <priority>요소를 모두 선택함.



    연산자(operator)



    XPath 표현식에서 사용할 수 있는 대표적인 연산자는 다음과 같다.


    연산자

    설명

    반환 타입

    -

    음의 부호(단항 연산자)

    숫자(number)

    *, div, mod

    곱셈, 나눗셈, 나머지 연산

    숫자(number)

    +, -

    덧셈, 뺄셈

    숫자(number)

    <, <=, >, >=

    비교 연산

    불리언(boolean)

    =, !=

    등가 비교 연산

    불리언(boolean)

    and

    논리 AND 연산

    불리언(boolean)

    or

    논리 OR 연산

    불리언(boolean)

    |

    여러 개의 노드셋을 동시에 계산함.

    노드셋(node-set)


    예제

    //language/name| //language/version : 모든 <language>요소의 <name>요소와 <version>요소를 모두 선택함.

    //name | //version : 현재 문서의 <name>요소와 <version>요소를 모두 선택함.

    /language/version/@status | //version : <language>요소의 <version>요소의 status 속성을 모두 선택하고, 현재 문서의 <version> 요소도 모두 선택함.


    Tip : 위의 표에서 연산자의 우선순위는 아래에서부터 위쪽으로 증가한다.

    즉, 맨 위의 음의 부호가 가장 우선순위가 높으며, | 연산자가 가장 우선순위가 낮다.



    728x90
    반응형

    'Mark Up > XML' 카테고리의 다른 글

    XML/XSD  (0) 2018.11.12
    XML/DTD  (0) 2018.11.09
    XML 노드  (0) 2018.11.05
    XML DOM  (0) 2018.11.05
    XSLT  (1) 2018.11.05
상단으로