2
  • We need to update <title> text, where the <id> is 11 to another text.
  • without knowing in which position the row <myrow> is.
  • Here are the rules for this, i need to use one of these connections listed below, since the Server only support those:

    Set objXML = Server.CreateObject("Microsoft.XMLDOM")
    Set objXML = Server.CreateObject("MSXML2.FreeThreadedDOMDocument")
    Set objXML = Server.CreateObject("MSXML2.DOMDocument")
    Set objXML = Server.CreateObject("MSXML2.DOMDocument.3.0")
    Set objXML = Server.CreateObject("MSXML2.DOMDocument.6.0")
    
  • Here it's the XML:

    <?xml version="1.0" encoding="iso-8859-2" ?>
    <xmldata>
      <myrow>
        <id>10</id>
        <title>title1</title>
        <msg>Hello world!</msg>
      </myrow>
      <myrow>
        <id>11</id>
        <title>title2</title>
        <msg>Hello world!</msg>
      </myrow>
      <myrow>
        <id>12</id>
        <title>title3</title>
        <msg>Hello world!</msg>
      </myrow>
    </xmldata>
    
  • Here it's the ASP VBScript code that we have at the moment:

    sub xmlUpdate(xpth)
      Set xmlObj = Server.CreateObject("Microsoft.XMLDOM")
      xmlObj.async = False
      xmlObj.setProperty "ServerHTTPRequest", True
      xmlObj.Load(xpth)
      If xmlObj.parseError.errorCode <> 0 Then
        Response.Write "Error Reading File - " & xmlObj.parseError.reason & "<p>"
      End If
      '---we need the rest of the code bellow-------------------------
    
      '---------------------------------------------------------------
      xmlObj.save(xpth)
    end sub
    

    Note: I already have a code that updates the first row, but is not good when we do not know where the row is.

3 Answers 3

2

Your

  1. question implies two nodes, one to change and one to base the change on; but I can't relate that to your specs ('to another text')
  2. sample .xml is not well-formed (non-closed myrows)
  3. code uses spurious () (.load, .save)
  4. attempt to .save even when .load fails makes no sense

To find the node to change, use an XPath looking for a xmldata having a myrow having an id of "11". You can adapt that strategy to find another node wrt which you want to compute the new title. Then find that node's title sibling via its parent and change the .text. In code:

Dim sXPath : sXPath   = "/xmldata/myrow/id[. = ""11""]"
Dim nd11   : Set nd11 = xmlObj.selectSingleNode(sXPath)
If nd11 Is Nothing Then
   WScript.Echo "failed:", sXPath
Else
   Dim ndTitle : Set ndTitle = nd11.parentNode.selectSingleNode("title")
   WScript.Echo "found:", nd11.tagName, nd11.text, ndTitle.text
   ndTitle.text = "pipapo"
   WScript.Echo "changed:", nd11.parentNode.xml
End If

output (simple script, not ASP):

cscript 27749208.vbs
found: id 11 title2
changed: <myrow>
        <id>11</id>
        <title>pipapo</title>
        <msg>Hello world!</msg>
</myrow>

Food for thought for efficiency aficionados:

A way is correct, if it gives correct results reliably. Some correct ways may be more efficient than others. The efficiency of ways that fail under realistic conditions need not be discussed.

The above strategy will succeed (without any change) if the myrow element looks like

changed: <myrow>
        <title>pipapo</title>
        <id>
                    11
                </id>
        <msg>Hello world!</msg>
</myrow>

InStr() for "<id>11</id>" will fail. You may tinker with a RegExp, but then there will be no title 'beyond that'. Feel free to do some magic with InStrRev() or InStr() on Mid(). But then please show reliably working code of less then about 10 lines. Make sure it handles initially empty title tags (either "<title/>" or "<title></title>") correctly.

What if the next version of the file contains

<mycol><id>11</id><title/></mycol>

This sample uses iso-8859-2 encoding. The standard encoding for XML is UTF-8. For that you'd need code to load and save the file using an ADODB.Stream. Try to do that 'more efficiently' as by using .load and .save.

Sign up to request clarification or add additional context in comments.

1 Comment

- You answer is also correct, even if the solution i need is to ASP , i will remember to use your script in a bath. - sorry i cannot vote on you guys, i need 15 reputation to do that, i will keep in my favorites and i will return later to vote, when i have the 15 Reputation .
1
  • I see that you search a solution for (ASP/VBScript).
  • even if the solution for (wscript/VBScript) looks similar since the language is the same, you will need some changes to make it work.
  • and yes, it will work with those connections you wrote in your comment.
  • Based on @Ekkehard's idea, I wrote an entire solution that will work with ASP-Classic (already tested).
Call test(server.mappatch("/myfolder/myxmlfile.xml"))

sub test(xpth)
    dim xmlObj,sxPth,ndRef,ndTarget,mytext,myReference,myTarget
    myReference="11" : myTarget="title" : mytext="some text"

    Set xmlObj = Server.CreateObject("Microsoft.XMLDOM")
    xmlObj.async = False
    xmlObj.setProperty "ServerHTTPRequest", True
    xmlObj.Load(xpth)
    If xmlObj.parseError.errorCode <> 0 Then
        Response.Write "Error Reading File - " & xmlObj.parseError.reason & "<p>"
    End If

    sxPth   = "/xmldata/myrow/id[. = """&myReference&"""]"
    Set ndRef = xmlObj.selectSingleNode(sxPth)
    If ndRef Is Nothing Then
       response.write "Not found:"& " " &sxPth& "<br />"
    Else
       Set ndTarget = ndRef.parentNode.selectSingleNode(myTarget)
       response.write "found reference:["& " " &ndRef.tagName& "][" &ndRef.text& "] <br /> target:[" &ndTarget.text& "]"
       ndTarget.text = mytext
       response.write " changed to:[" & myText & "] <br />"
    End If

    xmlObj.save(xpth)
end sub

Comments

0

Read the entire XML as a string. Search in the string for "<id>11</id>". If found, search for "<title>" beyond that, search for "</title>" beyond that, substitute text in the string, then use that as the new XML. Sometimes it's much easier to not parse the XML.

3 Comments

bad advice, you should use the proper tools for the task, not error prone hacks that will fail as soon as the input is not a simplified example.
I don't agree. There are many ways to accomplish a task. The correct way is the most efficient way. If doing a simple text search across the entire XML stream is quick, while loading a bunch of objects and methods is more involved, the correct way is the quick and easy way. How much code is required to load XML parsers, traverse the XML tree, and effect the change, compared to how much code is required to do a text substitution.
I make web applications as well as web services using classic ASP, Adobe LiveCycle, vb.net, and PHP, among others. SOAP is often used and XML is the only way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.