代码之家  ›  专栏  ›  技术社区  ›  MicSim

使用MSXML更改XML标记元素的节点名

  •  2
  • MicSim  · 技术社区  · 15 年前

    我想更改msxml xmldomelement的标记名,但不幸的是 节点名 属性是只读的。有没有什么直接的方法,或者我有没有做一些插入/替换和深度复制的子项?

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

    应该成为

    <xml> ...
        <newTagName>
          ... sub-elements
        </newTagName>
    <more xml> ...
    
    4 回复  |  直到 12 年前
        1
  •  2
  •   prostynick    15 年前

    根据文档对象模型,不能重命名节点。

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

    renamenode可以在dom级别3中使用,但不能在msxml库中使用。

        2
  •  2
  •   Anton Volkov    12 年前

    这是使用MSXML接口的“通用”重命名节点函数(objectpascal),工作正常,可以使用:

    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
  •  1
  •   MicSim    15 年前

    作为参考,我最后得到了一个replace函数,它将所有子节点复制到一个新创建的节点上:(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
    
        4
  •  1
  •   askmish    12 年前

    这是我的C++版本,也许你会更容易理解:

    #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);
    }