XPath를 사용하여 DOM을 쿼리할 때 네임스페이스 지정

이 문서에서는 개체의 selectSingleNode 및 selectNodes 메서드 IXMLDOMNode 와 함께 XPath 쿼리를 사용할 때 정규화된 이름을 사용해야 한다고 설명합니다.

원래 제품 버전: Microsoft XML 파서
원래 KB 번호: 294797

요약

MSXML(XML 파서) 3.0 릴리스 XPath 에서는 XML 문서를 쿼리하고 노드 또는 노드 집합을 반환하는 편리한 방법을 제공합니다. 개체의 selectSingleNodeselectNodes 메서드와 함께 쿼리를 IXMLDOMNode 사용하는 XPath 경우 정규화된 이름을 사용해야 합니다. 예를 들어 다음 XML 데이터가 있는 Book 노드를 선택하려면 다음을 수행합니다.

<?xml version ="1.0"?>
<a:Books xmlns:a="x-schema:bookschema.xml" >
    <a:Book>
        <title>Presenting XML</title>
        <author>Richard Light</author>
    </a:Book>
</a:Books>

를 URI(Uniform Resource Identifier)의 x-schema:bookschema.xml 별칭으로 사용하는 경우 해당 XPath 쿼리는 다음과 같습니다.

pXMLDoc->setProperty("SelectionNamespaces","xmlns:a='x-schema:bookschema.xml'");
pXMLDoc->documentElement->selectNodes("/a:Books/a:Book");

이 경우 정규화된 이름을 사용하는 것은 간단합니다. 그러나 기본 네임스페이스를 사용하는 경우 다음 예제와 같이 정규화된 이름을 사용하는 것이 더 어려울 수 있습니다.

<?xml version ="1.0"?>
<Books xmlns="x-schema:bookschema.xml" >
    <Book>
        <title>Presenting XML</title>
        <author>Richard Light</author>
    </Book>
</Books>

참고

노드 태그에는 접두사를 사용하지 않습니다. 정규화된 이름은 XPath 쿼리 내에서 계속 사용해야 합니다. 그렇지 않으면 일치하는 노드가 없으므로 쿼리(예: /Books/Book)는 결과를 반환하지 않습니다.

추가 정보

다음 Visual C++ 샘플은 이 기술을 보여 줍니다.

XPath를 사용하여 DOM을 쿼리할 때 네임스페이스를 지정하려면 다음 단계를 수행합니다.

  1. Win32 콘솔 프로젝트를 만들고 프로젝트에 새 .cpp 파일을 추가합니다. 다음 코드를 .cpp 파일에 붙여넣고 파일 이름을 Test.cpp.

    #include <stdio.h>
    
    #import "msxml3.dll"
    using namespace MSXML2;
    
    void dump_com_error(_com_error &e);
    
    int main(int argc, char* argv[])
    {
        CoInitialize(NULL);
        try{
            IXMLDOMDocument2Ptr pXMLDoc;
            HRESULT hr = pXMLDoc.CreateInstance(__uuidof(DOMDocument));
    
            pXMLDoc->async = false; // default - true,
    
            pXMLDoc->validateOnParse = true;
    
            hr = pXMLDoc->load("books.xml");
    
            if(hr!=VARIANT_TRUE)
            {
                IXMLDOMParseErrorPtr pError;
    
                pError = pXMLDoc->parseError;
                _bstr_t parseError =_bstr_t("At line ")+ _bstr_t(pError->Getline()) + _bstr_t("\n")+
                _bstr_t(pError->Getreason());
                MessageBox(NULL,parseError, "Parse Error",MB_OK);
                return -1;
            }
    
            hr = pXMLDoc->setProperty("SelectionLanguage", "XPath");
            hr = pXMLDoc->setProperty("SelectionNamespaces", "xmlns:a='x-schema:bookschema.xml'");
    
            IXMLDOMNodeListPtr pNodeList;
            pNodeList = pXMLDoc->documentElement->selectNodes("/a:Books/a:Book");
            int count = pNodeList->Getlength();
            char pLength[64];
            sprintf(pLength, "Total number of nodes selected is %d", count);
            MessageBox(NULL,pLength,"Test", MB_OK);
    
        }
        catch(_com_error &e)
        {
            dump_com_error(e);
            return -1;
        }
        return 0;
    }
    
    void dump_com_error(_com_error &e)
    {
        printf("Error\n");
        printf("\a\tCode = %08lx\n", e.Error());
        printf("\a\tCode meaning = %s", e.ErrorMessage());
        _bstr_t bstrSource(e.Source());
        _bstr_t bstrDescription(e.Description());
        printf("\a\tSource = %s\n", (LPCSTR) bstrSource);
        printf("\a\tDescription = %s\n", (LPCSTR) bstrDescription);
    }
    
  2. 다음 XML을 Test.cpp 동일한 프로젝트 폴더에 Books.xml 저장합니다.

    <?xml version ="1.0"?>
    <Books xmlns="x-schema:bookschema.xml" >
    <Book>
    <title>Presenting XML</title>
    <author>Richard Light</author>
    <pages>334</pages>
    </Book>
    <Book>
    <title>Mastering XML</title>
    <author>John Smith</author>
    <pages>209</pages>
    </Book>
    </Books>
    
  3. 다음 XML을 Test.cpp 동일한 프로젝트 폴더에 Bookschema.xml 저장합니다.

    <?xml version="1.0"?>
    <Schema xmlns="urn:schemas-microsoft-com:xml-data">
    <ElementType name="title" />
    <ElementType name="author" />
    <ElementType name="pages" />
    <ElementType name="Book" model="closed">
    <element type="title" />
    <element type="author" />
    <element type="pages" />
    </ElementType>
    <ElementType name="Books" model="closed">
    <element type="Book" />
    </ElementType>
    </Schema>
    
  4. 애플리케이션을 컴파일하고 실행합니다. 메시지 상자에는 쿼리에서 반환 XPath 되는 노드 수가 표시됩니다. 다음을 참조하세요.

    • 동일한 샘플 코드는 명시적 URI와 함께 네임스페이스로 사용할 수 있습니다.

    • 다음 줄에서

      IXMLDOMDocument2Ptr pXMLDoc;
      ...
      hr = pXMLDoc->setProperty("SelectionLanguage", "XPath");
      hr = pXMLDoc->setProperty("SelectionNamespaces", "xmlns:a='x-schema:bookschema.xml'");
      ...
      pNodeList = pXMLDoc->documentElement->selectNodes("/a:Books/a:Book");
      

      메서드는 setProperty 인터페이스에서 IXMLDOMDocument 사용할 수 없습니다.

정규화된 이름(QName)은 접두사 및 로컬 부분으로 구성됩니다. 접두사는 정규화된 이름의 네임스페이스 접두사를 제공하며 네임스페이스 URI와 연결되어야 합니다.

참조

XPath를 사용하여 사용자 정의 기본 네임스페이스에 대해 쿼리하는 방법