Link to home
Start Free TrialLog in
Avatar of Aleks
AleksFlag for United States of America

asked on

Help chaning value of tag inside an XML string

We have an ASP application with a MS SQL 2008 DB.
In one of the tables we save an XML string which has several tags and values saved in it. One of the tags is the "FieldReadOnly", inside we always save the value to be 'false'. Which is OK, we need it to be that way.
But in this particular page we need to update the value to 'true' for ALL tags inside the string, the page will read the string "strXML", then we need a routine that will change the string into the exact same code BUT with the value of FieldReadOnly changed to 'true'. And that should be called strXML2.

We then will use this string to send it to a web service. We have all the code BUT the routine to change the value from false to true, and this is where we need help. Below are examples of the two strings as they should look like.

1. We read the first string

    strXML = strXML & "<Field><FieldName>" & a(c) & "</FieldName><FieldValue>" & field & "</FieldValue><FieldReadOnly>false</FieldReadOnly><FieldVisibility>1</FieldVisibility><FieldRequired>false</FieldRequired><FieldFormat></FieldFormat><FieldMask>false</FieldMask><FieldCalcOverride>false</FieldCalcOverride><HiddenField>false</HiddenField></Field>"    

Open in new window

         
                 
2. We need to run the routing to change this:

 
<FieldReadOnly>false</FieldReadOnly>

Open in new window


into this:

 
<FieldReadOnly>true</FieldReadOnly>

Open in new window


On every tag found in the string. Then save that in a new string as the one below:

    strXML2 = strXML2 & "<Field><FieldName>" & a(c) & "</FieldName><FieldValue>" & field & "</FieldValue><FieldReadOnly>true</FieldReadOnly><FieldVisibility>1</FieldVisibility><FieldRequired>false</FieldRequired><FieldFormat></FieldFormat><FieldMask>false</FieldMask><FieldCalcOverride>false</FieldCalcOverride><HiddenField>false</HiddenField></Field>"     

Open in new window

Avatar of Athar Syed
Athar Syed
Flag of Kuwait image

If your table columns are actually the tag names, then you can simply create the xml using the select query

SELECT Col1, Col2, Col3, 'false' AS [FieldReadOnly]
FROM table(NOLOCK) FOR XML Auto

Open in new window

Avatar of Aleks

ASKER

They aren't. We need to use the first xml as our source
In that case it a matter of FIND & REPLACE in a string of XML.

Dim strXML As String = "blah_blah blahblah...blah<FieldReadOnly>false</FieldReadOnly>blahblah some more blah and more blah.."
Const BEGIN_tag As String = "<FieldReadOnly>"
Const END_tag As String = "</FieldReadOnly>"
Dim startPos As Integer = strXML.IndexOf(BEGIN_tag)
Dim endPos As Integer = strXML.IndexOf(END_tag)
Dim strXML2 As String = String.Empty

' everything from start fill start position (including the starting tag itself)
strXML2 = strXML.Substring(0, startPos + BEGIN_tag.Length)
strXML2 = strXML2 & "true"
' whatever is left after (and including the end tag)
strXML2 = strXML2 & strXML.Substring(endPos, strXML2.Length - endPos)

Open in new window

Avatar of Aleks

ASKER

Thanks. Will give this a try. I assume it works on any xml string that has those tags cuz they are all different. And they all have many tags. Like in the example.
I'll confirm later today.
You can wrap it up in a function and call the function for whatever tag you need

' function Declaration
Public Function ReplaceTagValue(xmlData As String, tagName As String, NewValue As String) As String
    Dim startTagName As String = "<" & tagName & ">"
    Dim endTagName As String = "</" & tagName & ">"
    Dim startPos As Integer = xmlData.IndexOf(startTagName)
    Dim endPos As Integer = xmlData.IndexOf(endTagName)

    If startPos < 0 OrElse endPos < 0 Then
        ' Start or End tag not found. Return the whole thing as it is
        Return xmlData
    End If

    dim newXml As String = xmlData.SubString(0, startPos + startTagName.Length)
    newXml += newValue
    newXml += xmlData.SubString(endPos, xmlData.Length - endPos)

    return newXml
End Function

' Implementing the wrapped function
xmlStr = ReplaceTagValue(xmlStr, "FieldReadOnly", "true")
xmlStr = ReplaceTagValue(xmlStr, "IceCreamFlavor", "Strawberry Ripple")

Open in new window

Avatar of Aleks

ASKER

There was a syntax error in the function. But we fixed it. The code below works but the problem is that it changes only the first tag to 'true', there are many 'fieldreadonly' tags in the string and all of them need to be updated.
So .. the function requires further tweaking .. can you help ?

Just in case, we are using Classic ASP.

Our code as it stands.

' function Declaration
Public Function ReplaceTagValue(xmlData, tagName, NewValue)
    Dim startTagName 
  startTagName = "<" & tagName & ">"
    Dim endTagName 
  endTagName= "</" & tagName & ">"
    Dim startPos 
  startPos= xmlData.IndexOf(startTagName)
    Dim endPos 
  endPos= xmlData.IndexOf(endTagName)

    If startPos < 0 Or endPos < 0 Then
        ' Start or End tag not found. Return the whole thing as it is
        Return xmlData
    End If

    dim newXml 
  newXml = xmlData.SubString(0, startPos + startTagName.Length)
    newXml = newXML + newValue
    newXml = newXML + xmlData.SubString(endPos, xmlData.Length - endPos)

    return newXml
End Function  
  
  Dim strXML2
  strXML2 = ReplaceTagValue(strXML,"FieldReadOnly","true")

Open in new window

Avatar of Aleks

ASKER

Ok, Im trying something else after reading about nodes and DOM in XML:

function myFunction(xml)
	Set xmlDoc = CreateObject("Microsoft.XMLDOM")
	xmlDoc.async = False
	xmlDoc.LoadXml(xml) 

    dim x, i, xmlDoc 
    set x = xmlDoc.selectNodes("fieldreadonly")
     for i = 0 to i < x.length
         x(i).childNodes(0).text = "true"
	 next
	return xmlDoc
End Function

Open in new window


Sadly, it does not work, im getting the following error:

Microsoft VBScript runtime error '800a01a8'
Object required: 'x(...)'
 file.asp, line 9
SOLUTION
Avatar of Athar Syed
Athar Syed
Flag of Kuwait image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Aleks

ASKER

This looks great!!!!
I changed correcty the name of the parent field (Called "ParentField")

sadly, It shows an error on this line:
      xmlRoot = xmlDoc.DocumentElement

Error is:
Microsoft VBScript runtime error '800a005b'
Object variable not set
Make sure your entire XPath is correct. If possible post up a bit of your XML data, about 2-3 records as it is in the actual file. Might be able to help better.
Avatar of Aleks

ASKER

XML sring is Extremelly long... but with this you get an Idea

<?xml version=""1.0"" encoding=""UTF-8"" standalone=""yes""?>
<ParentField>
   <Field>
     <FieldName>name1</FieldName>
     <FieldValue>value1</FieldValue>
     <FieldReadOnly>false</FieldReadOnly>
     <FieldVisibility>1</FieldVisibility>
     <FieldRequired>false</FieldRequired>
     <FieldFormat></FieldFormat>
     <FieldMask>false</FieldMask>
     <FieldCalcOverride>false</FieldCalcOverride>
      <HiddenField>false</HiddenField>
   </Field>
   <Field>
     <FieldName>name2</FieldName>
     <FieldValue>value2</FieldValue>
     <FieldReadOnly>false</FieldReadOnly>
     <FieldVisibility>1</FieldVisibility>
     <FieldRequired>false</FieldRequired>
     <FieldFormat></FieldFormat>
     <FieldMask>false</FieldMask>
     <FieldCalcOverride>false</FieldCalcOverride>
      <HiddenField>false</HiddenField>
   </Field>
</ParentField>
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Aleks

ASKER

Im really sorry to keep bothering you (classic ASP is a pain for me...)
What if instead of printing I would like the function to return the XML as a string again?

Tried
RETURN xDoc.xml

But it did not work (I assume its becausexDoc.xml is an xml instead of a string)
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Aleks

ASKER

Excellent Follow up, thank you!!!