Изменить NodeName элемента тега XML с помощью MSXML

Я хотел бы изменить имя тега элемента XMLDOME MSXML, но, к сожалению, свойство nodeName доступно только для чтения. Есть ли какой-нибудь простой способ сделать это, или мне нужно обойтись, выполнив некоторые операции вставки / замены и глубокого копирования детей?

<xml> ...
    <oldTagName>
      ... sub-elements
    </oldTagName>
<more xml> ...

Должен стать

<xml> ...
    <newTagName>
      ... sub-elements
    </newTagName>
<more xml> ...
13.10.2009 08:55:15
4 ОТВЕТА
РЕШЕНИЕ

Согласно объектной модели документа вы не можете переименовать узел.

См .: http://www.w3.org/TR/DOM-Level-2-Core/core.html#ID-1950641247.

RenameNode возможен в DOM Level 3, но не в библиотеке MSXML

2
13.10.2009 09:09:01

Просто для справки, я получил функцию замены, которая копирует все дочерние элементы во вновь созданный узел: (пример кода VB6)

Private Sub ReplaceNodeName(oDoc As DOMDocument, oElement As IXMLDOMElement, newName As String)
    Dim ohElement As IXMLDOMElement
    Dim sElement As IXMLDOMElement
    Dim oChild As IXMLDOMNode

    ' search the children '
    If Not oElement Is Nothing Then
        Set ohElement = oElement.parentNode
        Set sElement = oDoc.createElement(newName)

        For Each oChild In oElement.childNodes
            Call sElement.appendChild(oChild)
        Next

        Call ohElement.replaceChild(sElement, oElement)
    End If
End Sub
1
20.10.2009 08:38:07

Это «универсальная» функция переименования узлов (ObjectPascal), использующая интерфейсы MSXML, прекрасно работает и может быть использована:

function RenameXMLTag(e: IXMLNode; NewName: WideString): IXMLNode;
var
 Doc : IXMLDocument;
 NewElem, NParent : IXMLNode;
 DNOld, DNNew : IDOMNode;
 AC : IXMLNodeList;
 i: Integer;
begin
  Doc := e.OwnerDocument;
  NewElem := Doc.CreateNode(NewName, e.NodeType);
  while e.HasChildNodes do
    NewElem.DOMNode.AppendChild(e.DOMNode.firstChild);
  AC := e.AttributeNodes;
  for i := 0 to AC.Count - 1 do
    NewElem.Attributes[AC[i].NodeName] := AC[i].NodeValue;
  NParent := e.ParentNode;
  DNOld := e.DOMNode;
  DNNew := NewElem.DOMNode;
  NParent.DOMNode.replaceChild(DNNew, DNOld);
  Result := NewElem;
end;
3
24.04.2012 03:04:34

Это моя версия на С ++, может быть, вы поймете это проще:

#define SAFERELEASE(comobj) \
if (comobj)     \
{       \
 comobj->Release();  \
 comobj  = NULL;  \
}

void RenameElement(IXMLDOMElement * pElement, LPWSTR newName)
{
if (NULL == pElement)
    return;

IXMLDOMDocument * pParentDoc = NULL;
pElement->get_ownerDocument(&pParentDoc);

IXMLDOMElement * pNewElement = NULL;
pParentDoc->createElement(newName, &pNewElement);

VARIANT_BOOL bHasNodes;
pElement->hasChildNodes(&bHasNodes);

while (bHasNodes)
{
    IXMLDOMNode * pFirstChild = NULL;
    pElement->get_firstChild(&pFirstChild);
    pNewElement->appendChild(pFirstChild, NULL);
    pElement->hasChildNodes(&bHasNodes);
    SAFERELEASE(pFirstChild);
}
IXMLDOMNamedNodeMap * pAttrMap = NULL;
IXMLDOMNamedNodeMap * pAttrMapNew = NULL;
pElement->get_attributes(&pAttrMap);
pNewElement->get_attributes(&pAttrMapNew);
long nAttrLength = 0;
pAttrMap->get_length(&nAttrLength);
for (int n = 0; n < nAttrLength; n++)
{
    IXMLDOMNode * pListItem = NULL;
    pAttrMap->get_item(n, &pListItem);

    BSTR wsAttrName = NULL;
    pListItem->get_nodeName(&wsAttrName);

    BSTR wsAttrValue = NULL;
    pListItem->get_text(&wsAttrValue);

    IXMLDOMAttribute * pAttribute = NULL;
    pParentDoc->createAttribute((BSTR)wsAttrName, &pAttribute);
    pAttribute->put_value(CComVariant((BSTR)wsAttrValue));
    pAttrMapNew->setNamedItem(pAttribute, NULL);

    SAFERELEASE(pAttribute);
    SysFreeString(wsAttrValue);
    SysFreeString(wsAttrName);
    SAFERELEASE(pListItem);
}

IXMLDOMNode * pParent = NULL;
pElement->get_parentNode(&pParent);
pParent->replaceChild(pNewElement, pElement, NULL);

SAFERELEASE(pAttrMapNew);
SAFERELEASE(pAttrMap);
SAFERELEASE(pParent);
SAFERELEASE(pNewElement);
SAFERELEASE(pParentDoc);
}
1
21.10.2012 15:11:14
Пожалуйста, будьте более информативны в своем ответе. См .: Как ответить
askmish 21.10.2012 15:11:27