替换节点的整个XML属性

时间:2018-01-19 23:35:56

标签: xml vba

我有一个XML文档,我试图通过VBA修改。

struct productInfo
{
    string name;
    string location;
    int quantity;
    double price;
};

istream& operator>>(istream &in, productInfo &out)
{
    string line;

    if (!getline(in, out.name)) {
        // don't set failbit yet, in case this is just EOF...
        return in;
    }

    // at this point, a new product is encountered, so
    // any missing data is considered a failure...

    if (!getline(in, line)) {
        in.setstate(failbit);
        return in;
    }

    if (!(istringstream(line) >> out.quantity)) {
        in.setstate(failbit);
        return in;
    }

    if (!getline(in, out.location)) {
        in.setstate(failbit);
        return in;
    }

    if (!getline(in, line)) {
        in.setstate(failbit);
        return in;
    }

    if (!(istringstream(line) >> out.price)) {
        in.setstate(failbit);
        return in;
    }

    return in;
}

int ReadData(vector<productInfo> &products)
{
    ifstream infile("prog1.txt");
    int i = 0;

    productInfo info;
    while (infile >> info)
    {
        products.push_back(info);
        ++i;
    }

    infile.close();
    return i;
}

我想替换所选记录的整个XML属性。如果我为记录2选择了childnode,我可以看到xml属性中的所有代码,但该属性是只读的。有没有一种简单的方法可以用这样的格式化字符串替换xml属性,

<queryresults>
    <record id="1">
        <itemno>111111111111</itemno>
        <modelno>xxx-XXX-XXX</modelno>
        <itemtype>F</itemtype>
        <itemdesc>This is part number 1</itemdesc>
        <unitmeasure>Each</unitmeasure>
        <priceper/>
        <costtype>S</costtype>
        <sellprice>0</sellprice>
        <drawingno/>
        <itemstock>False</itemstock>
        <saleum>Each</saleum>
        <purchum>Each</purchum>
        <unitweight>0</unitweight>
        <weighttype/>
    </record>
    <record id="2">
        <itemno>111115555555</itemno>
        <modelno/>
        <itemtype>M</itemtype>
        <itemdesc>This is part number 2</itemdesc>
        <unitmeasure>Each</unitmeasure>
        <priceper/>
        <costtype>S</costtype>
        <sellprice>0</sellprice>
        <drawingno>xxx###33333</drawingno>
        <itemstock>False</itemstock>
        <saleum>Each</saleum>
        <purchum>Each</purchum>
        <unitweight>0</unitweight>
        <weighttype/>
    </record>
</queryresults>

而不是必须更改子节点中每个项目的值?

1 个答案:

答案 0 :(得分:0)

我认为这可能比你希望的更复杂......

Sub SwitchNodes()

    Dim XmlDoc1 As New MSXML2.DOMDocument30
    Dim XmlDoc2 As New MSXML2.DOMDocument30
    Dim objNodes As IXMLDOMNodeList, rec As Object, recNew As Object
    Dim ch, i

    Set XmlDoc1 = XmlDoc(Range("A1").Value)
    Set XmlDoc2 = XmlDoc(Range("B1").Value)

    If XmlDoc1 Is Nothing or XmlDoc2 Is Nothing Then Exit Sub

    Set rec = XmlDoc1.SelectSingleNode("//queryresults/record[@id='2']")
    If Not rec Is Nothing Then
        Set recNew = XmlDoc2.SelectSingleNode("//record")
        Debug.Print "Before **************" & vbLf & rec.xml
        If Not recNew Is Nothing Then
            'clear existing
            Do While rec.ChildNodes.Length > 0
                rec.RemoveChild rec.ChildNodes(0)
            Loop
            Debug.Print "Cleared **************" & vbLf & rec.xml
            'copy over
            Do While recNew.ChildNodes.Length > 0
                rec.appendChild recNew.ChildNodes(0)
            Loop
            Debug.Print "After **************" & vbLf & rec.xml
        End If
    Else
        Debug.Print "query results record not found!"
    End If
End Sub

'utility get an XML document from some xml
Function XmlDoc(xml As String) As MSXML2.DOMDocument60
    Dim rv As New MSXML2.DOMDocument60
    rv.async = False
    rv.LoadXML xml
    If rv.parseError.errorCode <> 0 Then
        MsgBox "Error!" & vbCrLf & _
        "  Line: " & rv.parseError.Line & vbCrLf & _
        "  Text:" & rv.parseError.srcText & vbCrLf & _
        "  Reason: " & rv.parseError.reason
        Set rv = Nothing
    End If 'parsed OK
    Set XmlDoc = rv
End Function