я пытаюсь получить конкретный идентификатор книги из прикрепленного здесь XML-файла (data.xml).
это работает нормально —- 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>
От https://msdn.microsoft.com/en-us/library/bb985161.aspx
Поскольку выражение может использовать шаблоны XPath 1.0 или XSL
синтаксис, должен быть способ указать язык выбора
перед использованием этих API. Для поддержания обратной совместимости с
существующий код, язык выбора по умолчанию — XSL Patterns. к
изменить текущий язык выбора на XPath, вызвать новый
Метод setProperty (см. IXMLDOMDocument2) с использованием SelectionLanguage
имя свойства и значение
Язык выбора DomDocument30 по умолчанию XSL Patterns
который является нестандартным предшественником реализации Microsoft XPath 1.0
,
И он неявно поддерживает использование шаблонов XSL с методом getElementsByTagName.
Поскольку DomDocument60 не поддерживает XSL Patterns
его язык выбора по умолчанию XPath
и его метод getElementsByTagName строго требует имени вместо шаблона или запроса. Так что вам нужно запросить с XPath с помощью SelectNodes метод.
В DomDocument60, эквивалент старого getElementsByTagName("book[@id='bk101']")
является selectNodes("//book[@id='bk101']")
Так что попробуйте:
xmlACPInput = sSourceInputXml->selectNodes(_bstr_t("//book[@id='bk101']"));