使用 C++ 在 IXMLDOMDocument 根元素中添加命名空间

发布于 2024-11-28 14:33:48 字数 2595 浏览 6 评论 0原文

我知道 stackoverflow 中有一个示例 使用 JS,但我需要使用 C++ 来完成此操作,并且由于一个奇怪的原因,如果属性名称以“xmlns:”为前缀,我无法使用 put_nodeValue() 将命名空间添加到根元素。

所以,我需要这样的东西:

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <media:group />
    <media:group />
</entry>

我正在尝试使用以下代码:

HRESULT hr = S_OK;
IXMLDOMDocument *doc;
IXMLDOMNode *entryElement;
IXMLDOMNode *groupElement;
IXMLDOMNode *groupElement2;
IXMLDOMNode *titleElement;
IXMLDOMNode *mediaAttribute;

// Initialize ...
hr = CoInitialize(NULL);
assert(hr == S_OK);

// Create (root) document
hr = CoCreateInstance(
    CLSID_DOMDocument30,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IXMLDOMDocument,
    (void**)&doc);
assert(hr == S_OK);

// Define namespaces
BSTR atomNamespace = L"http://www.w3.org/2005/Atom";
BSTR mediaNamespace = L"http://search.yahoo.com/mrss/";

// Define types
VARIANT elementType;
VariantInit(&elementType);
V_VT(&elementType) = VT_INT;
V_INT(&elementType) = NODE_ELEMENT;

VARIANT attributeType;
VariantInit(&attributeType);
V_VT(&attributeType) = VT_INT;
V_INT(&attributeType) = NODE_ATTRIBUTE;

// Add "entry" element
BSTR nodeName = L"entry";
hr = doc->createNode(elementType, nodeName, atomNamespace, &entryElement);
assert(hr == S_OK);

hr = doc->appendChild(entryElement, NULL);
assert(hr == S_OK);

// Add "media" namespace to "entry" element
nodeName = L"xmlns:media";
doc->createNode(attributeType, nodeName, atomNamespace, &mediaAttribute);

IXMLDOMNamedNodeMap *attributes;
entryElement->get_attributes(&attributes);

IXMLDOMNode *newAttribute;
hr = attributes->setNamedItem(mediaAttribute, &newAttribute);
assert(hr == S_OK);

VARIANT nodeValue;
VariantInit(&nodeValue);
V_VT(&nodeValue) = VT_BSTR;
V_BSTR(&nodeValue) = mediaNamespace;
hr = newAttribute->put_nodeValue(nodeValue);
assert(hr == S_OK);

// Add "group" element
nodeName = L"media:group";
hr = doc->createNode(elementType, nodeName, mediaNamespace, &groupElement);
assert(hr == S_OK);

hr = entryElement->appendChild(groupElement, NULL);
assert(hr == S_OK);

// Add second "group" element
nodeName = L"media:group";
hr = doc->createNode(elementType, nodeName, mediaNamespace, &groupElement2);
assert(hr == S_OK);

hr = entryElement->appendChild(groupElement2, NULL);
assert(hr == S_OK);

有什么想法吗?我正在使用 MSXML6。

I know there is an example in stackoverflow using JS, but I need to accomplish this using C++ and by a strange reason I am not able to add the namespace to the root element using put_nodeValue() if the attribute name is prefixed with "xmlns:".

So, I need something like this:

<entry xmlns="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/">
    <media:group />
    <media:group />
</entry>

I am trying with the following code:

HRESULT hr = S_OK;
IXMLDOMDocument *doc;
IXMLDOMNode *entryElement;
IXMLDOMNode *groupElement;
IXMLDOMNode *groupElement2;
IXMLDOMNode *titleElement;
IXMLDOMNode *mediaAttribute;

// Initialize ...
hr = CoInitialize(NULL);
assert(hr == S_OK);

// Create (root) document
hr = CoCreateInstance(
    CLSID_DOMDocument30,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IXMLDOMDocument,
    (void**)&doc);
assert(hr == S_OK);

// Define namespaces
BSTR atomNamespace = L"http://www.w3.org/2005/Atom";
BSTR mediaNamespace = L"http://search.yahoo.com/mrss/";

// Define types
VARIANT elementType;
VariantInit(&elementType);
V_VT(&elementType) = VT_INT;
V_INT(&elementType) = NODE_ELEMENT;

VARIANT attributeType;
VariantInit(&attributeType);
V_VT(&attributeType) = VT_INT;
V_INT(&attributeType) = NODE_ATTRIBUTE;

// Add "entry" element
BSTR nodeName = L"entry";
hr = doc->createNode(elementType, nodeName, atomNamespace, &entryElement);
assert(hr == S_OK);

hr = doc->appendChild(entryElement, NULL);
assert(hr == S_OK);

// Add "media" namespace to "entry" element
nodeName = L"xmlns:media";
doc->createNode(attributeType, nodeName, atomNamespace, &mediaAttribute);

IXMLDOMNamedNodeMap *attributes;
entryElement->get_attributes(&attributes);

IXMLDOMNode *newAttribute;
hr = attributes->setNamedItem(mediaAttribute, &newAttribute);
assert(hr == S_OK);

VARIANT nodeValue;
VariantInit(&nodeValue);
V_VT(&nodeValue) = VT_BSTR;
V_BSTR(&nodeValue) = mediaNamespace;
hr = newAttribute->put_nodeValue(nodeValue);
assert(hr == S_OK);

// Add "group" element
nodeName = L"media:group";
hr = doc->createNode(elementType, nodeName, mediaNamespace, &groupElement);
assert(hr == S_OK);

hr = entryElement->appendChild(groupElement, NULL);
assert(hr == S_OK);

// Add second "group" element
nodeName = L"media:group";
hr = doc->createNode(elementType, nodeName, mediaNamespace, &groupElement2);
assert(hr == S_OK);

hr = entryElement->appendChild(groupElement2, NULL);
assert(hr == S_OK);

Any idea? I am using MSXML6.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

绿光 2024-12-05 14:33:48

我得到了它!我收到了一些帮助:)

// Create (root) document
hr = CoCreateInstance(
    CLSID_DOMDocument30,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IXMLDOMDocument,
    (void**)&doc);
assert(hr == S_OK);

// Define namespaces
BSTR atomNamespace = L"http://www.w3.org/2005/Atom";
BSTR mediaNamespace = L"http://search.yahoo.com/mrss/";

CComVariant elementType = NODE_ELEMENT;
CComVariant attributeType = NODE_ATTRIBUTE;

// Add "entry" element
hr = doc->createNode(elementType, CComBSTR(L"entry"), atomNamespace, &entryNode);
assert(hr == S_OK);

hr = doc->appendChild(entryNode, NULL);
assert(hr == S_OK);

// Create "xmlns:media" attribute
CComPtr<IXMLDOMElement> element;
CComPtr<IXMLDOMAttribute> attr;

doc->createNode(attributeType, CComBSTR(L"xmlns:media"), mediaNamespace, &attrNode);
assert(hr == S_OK);

hr = attrNode->put_nodeValue(CComVariant(mediaNamespace));
assert(hr == S_OK);

entryNode->QueryInterface(&element);
assert(hr == S_OK);

attrNode->QueryInterface(&attr);
assert(hr == S_OK);

element->setAttributeNode(attr, NULL);

// Add first "group" element
hr = doc->createNode(elementType, CComBSTR(L"media:group"), mediaNamespace, &groupNode1);
assert(hr == S_OK);

hr = entryNode->appendChild(groupNode1, NULL);
assert(hr == S_OK);

// Add second "group" element
hr = doc->createNode(elementType, CComBSTR(L"media:group"), mediaNamespace, &groupNode2);
assert(hr == S_OK);

hr = entryNode->appendChild(groupNode2, NULL);
assert(hr == S_OK);

我只需要将其添加为属性并查询正确的接口。

I got it! I received some help :)

// Create (root) document
hr = CoCreateInstance(
    CLSID_DOMDocument30,
    NULL,
    CLSCTX_INPROC_SERVER,
    IID_IXMLDOMDocument,
    (void**)&doc);
assert(hr == S_OK);

// Define namespaces
BSTR atomNamespace = L"http://www.w3.org/2005/Atom";
BSTR mediaNamespace = L"http://search.yahoo.com/mrss/";

CComVariant elementType = NODE_ELEMENT;
CComVariant attributeType = NODE_ATTRIBUTE;

// Add "entry" element
hr = doc->createNode(elementType, CComBSTR(L"entry"), atomNamespace, &entryNode);
assert(hr == S_OK);

hr = doc->appendChild(entryNode, NULL);
assert(hr == S_OK);

// Create "xmlns:media" attribute
CComPtr<IXMLDOMElement> element;
CComPtr<IXMLDOMAttribute> attr;

doc->createNode(attributeType, CComBSTR(L"xmlns:media"), mediaNamespace, &attrNode);
assert(hr == S_OK);

hr = attrNode->put_nodeValue(CComVariant(mediaNamespace));
assert(hr == S_OK);

entryNode->QueryInterface(&element);
assert(hr == S_OK);

attrNode->QueryInterface(&attr);
assert(hr == S_OK);

element->setAttributeNode(attr, NULL);

// Add first "group" element
hr = doc->createNode(elementType, CComBSTR(L"media:group"), mediaNamespace, &groupNode1);
assert(hr == S_OK);

hr = entryNode->appendChild(groupNode1, NULL);
assert(hr == S_OK);

// Add second "group" element
hr = doc->createNode(elementType, CComBSTR(L"media:group"), mediaNamespace, &groupNode2);
assert(hr == S_OK);

hr = entryNode->appendChild(groupNode2, NULL);
assert(hr == S_OK);

I just needed to add it as attribute and query the correct interfaces.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文