getElementsByTagName()不能处理DOMDOCUMENT60的特殊字符

getElementsByTagName() is not working with special characters for DOMDOCUMENT60

本文关键字:DOMDOCUMENT60 特殊字符 处理 不能 getElementsByTagName      更新时间:2023-10-16

我试图从这里附加的XML文件(data.xml)获得一个特定的书id。这是工作良好---- getElementsByTagName(_bstr_t("book"))但是当我搜索某本书的时候异常——getElementsByTagName(_bstr_t("book[@id='bk101']"))

此问题见于DOMDOCUMENT60

我不知道为什么它不能处理特殊字符。有人遇到过这个问题或者有什么建议吗?

#include "stdafx.h"
#include<iostream>
#include "Msxml.h"
#import "msxml6.dll"
using namespace MSXML2;
#include "stdlib.h"
#include "stdio.h"
#include <string>
using namespace std;
void LoadXML()
{
    HRESULT hr1, hr;
    hr1 = CoInitialize(NULL); //without this, cocreateinstance returns null pointer.
    _variant_t vaNodeVal("C://data.xml");
    VARIANT var1 = vaNodeVal;
    CComPtr<IXMLDOMDocument2> sSourceInputXml = 0;
    hr = sSourceInputXml.CoCreateInstance(__uuidof(MSXML2::DOMDocument60));
    int ii=10;
    if (hr == S_OK && sSourceInputXml != NULL)
    {
        hr = sSourceInputXml->load(var1);
        int err = GetLastError();
        ii=20;
        try
        {
            ii = 30;
            CComQIPtr<MSXML2::IXMLDOMNodeList> xmlACPInput;
            std::cout << "nworking";
            xmlACPInput = sSourceInputXml->getElementsByTagName(_bstr_t("book[@id='bk101']")); //throwing exception 
            std::cout << "n not working";
            long lCount = 0;
            xmlACPInput->get_length(&lCount);
            bool isACP = false;
            if (lCount == 0)
            {
                isACP = false;
            }
            else
            {
                isACP = true;
            }
        }
        catch (exception ex)
        {
            ii = 1101;
        }
        catch (...)
        {
            ii = 1100;

        }
    }

    CoUninitialize();  
}

int _tmain(int argc, _TCHAR* argv[])
{
    LoadXML();
    return 0;
}

<?xml version="1.0"?>
<catalog>
  <book id="bk101">
    <author>Gambardella, Matthew</author>
    <title>XML Developer's Guide</title>
    <genre>Computer</genre>
    <price>44.95</price>
    <publish_date>2000-10-01</publish_date>
    <description>
      An in-depth look at creating applications
      with XML.
    </description>
  </book>
  <book id="bk102">
    <author>Ralls, Kim</author>
    <title>Midnight Rain</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2000-12-16</publish_date>
    <description>
      A former architect battles corporate zombies,
      an evil sorceress, and her own childhood to become queen
      of the world.
    </description>
  </book>
  <book id="bk103">
    <author>Corets, Eva</author>
    <title>Maeve Ascendant</title>
    <genre>Fantasy</genre>
    <price>5.95</price>
    <publish_date>2000-11-17</publish_date>
    <description>
      After the collapse of a nanotechnology
      society in England, the young survivors lay the
      foundation for a new society.
    </description>
  </book>
</catalog>

From https://msdn.microsoft.com/en-us/library/bb985161.aspx

因为表达式可以使用XPath 1.0或XSL模式语法方面,需要有一种方法来指定选择语言在使用这些api之前。保持向后兼容性现有代码,默认选择语言是XSL Patterns。来将当前选择语言更改为XPath,调用newsetProperty方法(参见IXMLDOMDocument2),使用SelectionLanguage属性名和值

DomDocument30的默认选择语言是XSL Patterns,这是XPath 1.0的非标准微软实现前身。
它隐式地支持使用带有getElementsByTagName方法的XSL模式。

由于DomDocument60不支持XSL Patterns,它的默认选择语言是XPath,并且它的getElementsByTagName方法严格要求一个名称而不是模式或查询。因此需要使用selectNodes方法使用XPath进行查询。

在DomDocument60中,相当于旧getElementsByTagName("book[@id='bk101']")的是selectNodes("//book[@id='bk101']")

所以试试吧:

xmlACPInput = sSourceInputXml->selectNodes(_bstr_t("//book[@id='bk101']"));