XPath ile DOM'yi sorgularken Ad Alanı belirtme

Bu makalede, nesnenin selectSingleNode ve selectNodes yöntemleriyle XPath sorgusu kullanırken nitelenmiş adlar IXMLDOMNode kullanmanız gerektiği açıklanır.

Orijinal ürün sürümü: Microsoft XML Ayrıştırıcısı
Özgün KB numarası: 294797

Özet

XML Ayrıştırıcısı (MSXML) 3.0 sürümüyle, XPath XML belgelerini sorgulamak ve bir düğüm veya düğüm kümesi döndürmek için kullanışlı bir yol sağlar. nesnesinin selectSingleNode ve selectNodes yöntemleriyle sorgu kullandığınızdaXPath, nitelenmiş adlar IXMLDOMNode kullanmanız gerekir. Örneğin, aşağıdaki XML verilerini içeren Kitap düğümünü seçmek için:

<?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>

Tekdüzen Kaynak Tanımlayıcısı 'nın x-schema:bookschema.xml (URI) diğer adı olarak bir kullanırsak, karşılık gelen XPath sorgusu aşağıdaki gibidir:

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

Bu durumda, tam adı kullanmak basittir. Ancak, varsayılan ad alanı kullanıldığında, aşağıdaki örnekte olduğu gibi tam adı kullanmak daha zor olabilir:

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

Not

Düğüm etiketlerinde ön ek kullanılmaz. Nitelenmiş ad XPath sorgusunun içinde kullanılmaya devam edilmelidir, aksi takdirde eşleşen düğüm olmadığından sorgu (örneğin, /Books/Book) sonuç döndürmez.

Daha fazla bilgi

Tekniği göstermek için aşağıdaki Visual C++ örneği sağlanır.

DOM'u XPath ile sorgularken ad alanını belirtmek için şu adımları izleyin:

  1. Win32 konsol projesi oluşturun ve projeye yeni bir .cpp dosyası ekleyin. Aşağıdaki kodu .cpp dosyasına yapıştırın ve dosyayı Test.cpp adlandırın:

    #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. Aşağıdaki XML'yi Books.xml olarak Test.cpp olarak aynı proje klasörüne kaydedin.

    <?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. Aşağıdaki XML'yi Bookschema.xml olarak Test.cpp olarak aynı proje klasörüne kaydedin.

    <?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. Uygulamayı derleyin ve çalıştırın. İleti kutusu, sorgu tarafından XPath döndürülen düğüm sayısını gösterir. Aşağıdakilere bakın:

    • Aynı örnek kod, ad alanı olarak açık bir URI ile kullanılabilir.

    • Aşağıdaki satırlarda

      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 yöntemi arabirimiyle IXMLDOMDocument kullanılamaz.

Nitelenmiş ad (QName), bir ön ek ve yerel bir bölümden oluşur. Ön ek, nitelenmiş adın ad alanı ön ekini sağlar ve bir ad alanı URI'siyle ilişkilendirilmelidir.

Başvurular

Kullanıcı tanımlı varsayılan ad alanına karşı sorgulamak için XPath'i kullanma