Link to home
Start Free TrialLog in
Avatar of newbie29
newbie29

asked on

modify script to handle child nodes

Hello,
I have a xml with quite a few child nodes, I normally have a flat xml file and whenever I would need to update xml fields
I would easily pass mulitple fields and values to the proxy.asp to process all the fields separated by "|"
The problem is If I would need to add extra node in a specific child node.

Just to make my point clear, say I have the following xml file

<record>
      <fname> john  </fname>
      <lname>  smith</lname>
      <book>
            <book_title> adventure </book_title>
            <book_price> 343.00 </book_price>
      </book>
      <email_address> email@emaill.com</email_address>
      <contact> 234234 </contact>
 
</record>


I have a function in ASP to deal for the flat xml file but I am confused to update/modify the existing script
to handle the above situation, for example, if i want to add extra node in <book> like <book_last_updated>

The request I am doing is through ajax and following is the ajax syntax I have

  $.ajax({
           type: "POST",
           url: "some.asp",
           data: "action=save&uid="+id +"&values="+v+"|&fields=" + escape("book/bool_title|book/book_last_updated")

Please also have ASP script attached

Your help is much appreciated...

Regards
sam
Avatar of newbie29
newbie29

ASKER




 <%
    Dim record
    Record = "record"
      sKey = Request("k")

      sDBM = Request.QueryString("dbm")

   sField = Request("fields")
    sValue = Request("values")
       If Lcase(request("action")) = "save" Then
            SaveFields()                         
      End If
 
%>

<%
' ******************************************************************************
Function SaveFields()
 
Dim sKey,sDisplayMode
Dim fso,oFiles,oFile,sFilename,sText
Dim sLangCode,sLanguageName,sTextTag,sISBNList,sTemplate,sSecondLevel
Dim sRefNo,sName,sFriendlyName,sType,sModifiedDate,sModifiedBy
Dim bVisible,bEditable
Dim oXMLFieldDefs,oNode,oNodeList,oTmp  
     
     'Get the key.
      
      
      
      sFilename = sKey & ".xml"
      
   
      sFullPath = FindFilePath(sKey, RDBM_INDEX_FOLDER)
      if sFullPath = "" Then
            ' try the root data folder which is where new Records will be created
            ' This is in case the index is not up to date.
            sFullPath = RDBM_DB_FOLDER & "\data\" & sFilename
      End If
         '/mp oXMLDoc
      
      
         Set oXMLDoc = createObject("MSXML2.DOMDocument")
         oXMLDoc.async = false
         oXMLDoc.Load sFullPath
          
         aFields = Split(sField, "|")
         aValues = Split(sValue, "|")
         ' This won't handle pipe separated multi-instance fields..
         ' Also - doesn't save tmp copy to Edited folder..
         For i = 0 To UBound(aFields)
                Set oNode = oXMLDoc.DocumentElement.selectSingleNode("//" & aFields(i))
                            
                If Not oNode Is Nothing Then
                      oNode.text = aValues(i)
                Else
                      Set oNode = oXMLDoc.createElement(aFields(i))
                      oNode.text = aValues(i)
                      oXMLDoc.documentElement.appendChild oNode
                End if
          Next
 
        ' Also no sort..
        oXMLDoc.Save sFullPath
        'Response.Write Replace(Replace(sField, "_", " "), "|", ", ") & " updated successfully."
        '' Finally consider re-indexing as well..
        Response.write WriteResponse(0)
     
End Function

Can someone please help me on this?

Please tell me how to find "book_feature" node from the xml document after loading it.

Set oNode = oXMLDoc.DocumentElement.selectSingleNode(?)
Avatar of hielo
If you know the path to the parent of the node you want to attach  the new node to. So, on your example you would need:
Set oNode = oXMLDoc.DocumentElement.selectSingleNode("//record/book")
Set newNode = oXMLDoc.createElement("book_feature")
newNode.text="awesome"
oNode.appendChild( newNode )
hello hielo,
the problem is that I would never able to fix the node here
Set oNode = oXMLDoc.DocumentElement.selectSingleNode("//record/book")


Because the same script is also been used to update

Set oNode = oXMLDoc.DocumentElement.selectSingleNode("//record)

I was thinking that using the same I can pass the complete node name but that does not seems to have worked for me ...

the script is yet another one ... but unable to get my head over it
	Set oXMLDoc = CreateObject("MSXML2.DOMDocument")
			'oXMLDoc.preserveWhiteSpace = true
			oXMLDoc.Async = False
			blob = readFile(sFullPath)
			'blob = UTF8ToUniStr(blob)
			oXMLDoc.LoadXml blob
			' mp create list of files that have change for the DB Make Live function
			x = UpdateThisFile(sFullPath, RDBM_DB_FOLDER & "\edited\FilesToIndex.dat")
			oXMLDoc.Save sTempFile 'Save temp file to 'edited' folder.
			
			sModifiedBy = "CMS" 'TODO
			
			'The XML document containing the definitions of the fields to be edited.
			Set oXMLFieldDoc = CreateObject("MSXML2.DOMDocument")
			oXMLFieldDoc.Async = False
			oXMLFieldDoc.Load ADMIN_WWW_FOLDER & "\include\" & RDBM_FIELD_DEF_FILE
			
			'Retrieve data for all fields.
			For Each oFieldDef In oXMLFieldDoc.DocumentElement.SelectNodes("field")
				sType = oFieldDef.SelectSingleNode("type").Text
				sRefNo = oFieldDef.SelectSingleNode("name").Text
				'Set parent node.
				If InStr(sRefNo,"/") Then
					sParent=Left(sRefNo,InStr(sRefNo,"/")-1)
					Set oNode = oXMLDoc.DocumentElement.SelectSingleNode(sParent)
					If oNode Is Nothing Then
						'Parent node is not present - create.
						Set oNode = oXMLDoc.CreateNode(1,sParent,"")
						oXMLDoc.DocumentElement.AppendChild(oNode)
					End If
					sName = Mid(sRefNo,InStr(sRefNo,"/")+1)
				Else
					Set oNode = oXMLDoc.DocumentElement
					sName = sRefNo
				End If
				'Set node.
				Set oNodeList = oNode.SelectNodes(sName)
				If Not oNodeList Is Nothing Then
					'Delete existing text data.
					For Each oTmp In oNodeList
						oNode.RemoveChild oTmp
						'For i = 0 To oTextNode.ChildNodes.Length - 1
						'	oTextNode.RemoveChild oTextNode.ChildNodes.Item(i)
						'Next
					Next
				End If
				
				If Request.Form("fv_" & sName) <> "" Then
					Set oTextNode = oXMLDoc.CreateNode(1,sName,"")
					oNode.AppendChild(oTextNode)
					'Add the new data.
					UpdateText oXMLDoc, oTextNode, sType, "fv_" & sName
				End If
			Next
			
				'response.write sXMLFile
				'response.end
						
			'Update last modified information.
			Set oTextNode = oXMLDoc.DocumentElement.SelectSingleNode("last_updated")
			If oTextNode Is Nothing Then
				Set oTextNode = oXMLDoc.CreateNode(1,"last_updated","")
				oXMLDoc.DocumentElement.AppendChild(oTextNode)
			End If
			oTextNode.Text = Year(Now()) & PadZ(Month(Now()),2) & PadZ(Day(Now()),2) & "|" & PadZ(Hour(Now()),2) & ":" & PadZ(Minute(Now()),2) & ":" & PadZ(Second(Now()),2)
			
			Set oTextNode = oXMLDoc.DocumentElement.SelectSingleNode("last_updated_by")
			If oTextNode Is Nothing Then
				Set oTextNode = oXMLDoc.CreateNode(1,"last_updated_by","")
				oXMLDoc.DocumentElement.AppendChild(oTextNode)
			End If
			oTextNode.Text = sModifiedBy
			
			'' Sort the XML. Beware, if you are relying on certain fields remaining as CDATA Elements then
			'' You will need to specify Element names in the SortNode Function below..
			'' SortNodeCDATAElements are set in admin_def
			x = SortNode(oXMLDoc, "a", SortNodeCDATAElements)
			oXMLDoc.Save sXMLFile

Open in new window

All what I have to do using the script above is update the xml file with the data recieved, the following 2 variable storing the data from the previous page

ajax Request:
sField ="book/book_title|book_last_updated)
sValue ="hielo|20080410"

proxy page
sField = Request("fields")
sValue = Request("data")
>>Because the same script is also been used to update
What does that mean?

>>I was thinking that using the same I can pass the complete node name
You can pass the complete path to the node you want to attache a new node to. To clarify, if you want to attach a new node to <book>, you need to suppy the path to the book node.
for now I am only updating book node but in future if someone wants to add another set of nodes then I would have to change the script again to read something else....

hielo,
can you please have a look to the script attached and please modify it according to my requirement
to fetch data from sField and sValue and update the xml file
--------------------------------------------------------------------------------
sField ="book/book_title|book_last_updated)
sValue ="hielo|20080410"

proxy page
sField = Request("fields")
sValue = Request("data")
-------------------------------------------------------------------------------

hope you understand what I am after ..!

thanks for your help


Set oXMLFieldDoc = CreateObject("MSXML2.DOMDocument")
			oXMLFieldDoc.Async = False
			oXMLFieldDoc.Load "test.xml"
			
			'Retrieve data for all fields.
			For Each oFieldDef In oXMLFieldDoc.DocumentElement.SelectNodes("field")
				sType = oFieldDef.SelectSingleNode("type").Text
				sRefNo = oFieldDef.SelectSingleNode("name").Text
				'Set parent node.
				If InStr(sRefNo,"/") Then
					sParent=Left(sRefNo,InStr(sRefNo,"/")-1)
					Set oNode = oXMLDoc.DocumentElement.SelectSingleNode(sParent)
					If oNode Is Nothing Then
						'Parent node is not present - create.
						Set oNode = oXMLDoc.CreateNode(1,sParent,"")
						oXMLDoc.DocumentElement.AppendChild(oNode)
					End If
					sName = Mid(sRefNo,InStr(sRefNo,"/")+1)
				Else
					Set oNode = oXMLDoc.DocumentElement
					sName = sRefNo
				End If
				'Set node.
				Set oNodeList = oNode.SelectNodes(sName)
				If Not oNodeList Is Nothing Then
					'Delete existing text data.
					For Each oTmp In oNodeList
						oNode.RemoveChild oTmp
						'For i = 0 To oTextNode.ChildNodes.Length - 1
						'	oTextNode.RemoveChild oTextNode.ChildNodes.Item(i)
						'Next
					Next
				End If
				
				If Request.Form("fv_" & sName) <> "" Then
					Set oTextNode = oXMLDoc.CreateNode(1,sName,"")
					oNode.AppendChild(oTextNode)
					'Add the new data.
					UpdateText oXMLDoc, oTextNode, sType, "fv_" & sName
				End If
			Next
			
				'response.write sXMLFile
				'response.end
						
			'Update last modified information.
			Set oTextNode = oXMLDoc.DocumentElement.SelectSingleNode("last_updated")
			If oTextNode Is Nothing Then
				Set oTextNode = oXMLDoc.CreateNode(1,"last_updated","")
				oXMLDoc.DocumentElement.AppendChild(oTextNode)
			End If
			oTextNode.Text = Year(Now()) & PadZ(Month(Now()),2) & PadZ(Day(Now()),2) & "|" & PadZ(Hour(Now()),2) & ":" & PadZ(Minute(Now()),2) & ":" & PadZ(Second(Now()),2)
			
			Set oTextNode = oXMLDoc.DocumentElement.SelectSingleNode("last_updated_by")
			If oTextNode Is Nothing Then
				Set oTextNode = oXMLDoc.CreateNode(1,"last_updated_by","")
				oXMLDoc.DocumentElement.AppendChild(oTextNode)
			End If
			oTextNode.Text = sModifiedBy
			
			oXMLDoc.Save sXMLFile
		

Open in new window

<%=Right(fv("eh_review"), len(fv("eh_review")) - len(sDescription)) %>

can you please copy above and paste it in here

https://www.experts-exchange.com/questions/23307602/toggle-script-to-apply-in-the-dynamic-content.html
If I understand you correctly this:
>>sField ="book/book_title|book_last_updated)
is meant to create a node named book_last_updated and append it to book/book_title

but what is the significance of this:
>>sValue ="hielo|20080410"
sField = "book/book_title|book/last_updated"
sValue ="hielo|20080410"


sorry there was a typo earlier, sField contains the <tag> name and sValue hold their values

for example if you see the
http://213.253.134.6/dtsearchk/pubnews-previews/bib/data/9781862305076.xml
i am after <ehaus> node, it contains feature where i need to store Y or N and need to create another node called eh_last_modified and add the current date to it ...



Is there any way I can give you double points ? If yes the I will for this question.


I manage to make some script here which load the current (9781862305076.xml) file and another file (xml file 2) to get the extra fields name to append in the 9781862305076.xml,

if you could please go though this code and see if what i am doing is correct? i have not tested it but i think it might have errors in it....


xml file 1:
http://213.253.134.6/dtsearchk/pubnews-previews/bib/data/9781862305076.xml

xml file 2:
<?xml version="1.0" encoding="UTF-8" ?>
<fieldlist>
      <field primarykey="Y">
            <name>ref_no</name>
            <friendly_name>Reference No</friendly_name>                  
            <type>TEXT</type>
            <visible>N</visible>
            <editable>N</editable>

      </field>
      <field>
            <name>ctitle</name>
            <friendly_name>Combined Title</friendly_name>                  
            <type>TEXT</type>
            <visible>Y</visible>                  
            <editable>N</editable>

      </field>
      
      
      <field>
            <name>ehaus/eh_review</name>
            <friendly_name>My Review Text</friendly_name>
            <type>HTML</type>
            <visible>Y</visible>
            <editable>Y</editable>

      </field>
      <field>
            <name>ehaus/eh_cat</name>
            <friendly_name>Category</friendly_name>
            <type>TEXT</type>
            <visible>Y</visible>
            <editable>Y</editable>

      </field>
      <field>
            <name>ehaus/eh_cat_code</name>
            <friendly_name>Category Code</friendly_name>
            <type>TEXT</type>
            <visible>Y</visible>
            <editable>Y</editable>

      </field>
      <field>
            <name>ehaus/eh_feature</name>
            <friendly_name>Special feature</friendly_name>
            <type>BOOLEAN</type>
            <visible>Y</visible>
            <editable>Y</editable>

      </field>
      <field>
            <name>ehaus/eh_date_loaded</name>
            <friendly_name>Date Loaded</friendly_name>
            <type>TEXT</type>
            <visible>Y</visible>
            <editable>N</editable>

      </field>
      <field>
            <name>ehaus/eh_sort_feature</name>
            <friendly_name>Sort Feature</friendly_name>
            <type>TEXT</type>
            <visible>Y</visible>
            <editable>N</editable>

      </field>
      <field>
            <name>vx_first_name</name>
            <friendly_name></friendly_name>
            <type>TEXT</type>
            <visible>N</visible>
            <editable>N</editable>

      </field>
      
      
</fieldlist>
' ******************************************************************************
Function SaveFields()
 
Dim sDisplayMode
Dim fso,oFiles,oFile,sFilename,sText
Dim sLangCode,sLanguageName,sTextTag,sISBNList,sTemplate,sSecondLevel
Dim sRefNo,sName,sFriendlyName,sType,sModifiedDate,sModifiedBy
Dim bVisible,bEditable
Dim oXMLFieldDefs,oNode,oNodeList,oTmp  
    
 
	'response.write oXMLFieldDefs.parseerror.reason
	'Retrieve the XML document containing the actual data.
	sFilename = sKey & ".xml"
 
	if sFullPath = "" Then
		' try the root data folder which is where new Records will be created
		' This is in case the index is not up to date.
		sFullPath = RDBM_DB_FOLDER & "\data\" & sFilename
	End If
	   '/mp oXMLDoc
	
	 sXMLFile = sFullPath
	   Set oXMLDoc = createObject("MSXML2.DOMDocument")
	   oXMLDoc.async = false
	   oXMLDoc.Load sFullPath
    	
		If InfiniteUndo = True Then				
				FileUndo = sFilename & "_" & Year(Now()) & "-" & PadZ(Month(Now()),2) & "-" & PadZ(Day(Now()),2) & "-" & PadZ(Hour(Now()),2) & ".xml"
		Else
				FileUndo = sFilename
		End If
		
		sTempFile = RDBM_DB_FOLDER & "\edited\" & FileUndo
		
		Set oXMLDoc = CreateObject("MSXML2.DOMDocument")
			'oXMLDoc.preserveWhiteSpace = true
			oXMLDoc.Async = False
			blob = readFile(sFullPath)
			'blob = UTF8ToUniStr(blob)
			oXMLDoc.LoadXml blob
			' mp create list of files that have change for the DB Make Live function
			x = UpdateThisFile(sFullPath, RDBM_DB_FOLDER & "\edited\FilesToIndex.dat")
			oXMLDoc.Save sTempFile 'Save temp file to 'edited' folder.
			
		sModifiedBy = "AJAX" 
			
		'The XML document containing the definitions of the fields to be edited.
		Set oXMLFieldDoc = CreateObject("MSXML2.DOMDocument")
			oXMLFieldDoc.Async = False
			oXMLFieldDoc.Load ADMIN_WWW_FOLDER & "\include\" & xmlfile2
			
			
        For Each oFieldDef In oXMLFieldDoc.DocumentElement.SelectNodes("field")
                                sType = oFieldDef.SelectSingleNode("type").Text
                                sRefNo = oFieldDef.SelectSingleNode("name").Text
                                'Set parent node.
                                If InStr(sRefNo,"/") Then
                                        sParent=Left(sRefNo,InStr(sRefNo,"/")-1)
                                        Set oNode = oXMLDoc.DocumentElement.SelectSingleNode(sParent)
                                        If oNode Is Nothing Then
                                                'Parent node is not present - create.
                                                Set oNode = oXMLDoc.CreateNode(1,sParent,"")
                                                oXMLDoc.DocumentElement.AppendChild(oNode)
                                        End If
                                        sName = Mid(sRefNo,InStr(sRefNo,"/")+1)
                                Else
                                        Set oNode = oXMLDoc.DocumentElement
                                        sName = sRefNo
                                End If
                                'Set node.
                                Set oNodeList = oNode.SelectNodes(sName)
                                If Not oNodeList Is Nothing Then
                                        'Delete existing text data.
                                        For Each oTmp In oNodeList
                                                oNode.RemoveChild oTmp                                                
                                        Next
                                End If
                                
                                If sName <> "" Then
                                        Set oTextNode = oXMLDoc.CreateNode(1,sName,"")
                                        oNode.AppendChild(oTextNode)
                                        'Add the new data.                                        
										oTextNode.Text = sName
                                End If
         Next 
 
			'Update last modified information.
			Set oTextNode = oXMLFieldDoc.DocumentElement.SelectSingleNode("eh_last_updated")
			If oTextNode Is Nothing Then
				Set oTextNode = oXMLDoc.CreateNode(1,"eh_last_updated","")
				oXMLDoc.DocumentElement.AppendChild(oTextNode)
			End If
			oTextNode.Text = Year(Now()) & PadZ(Month(Now()),2) & PadZ(Day(Now()),2) 
				
				
		'Update last modified information.
			Set oTextNode = oXMLDoc.DocumentElement.SelectSingleNode("last_updated")
			If oTextNode Is Nothing Then
				Set oTextNode = oXMLDoc.CreateNode(1,"last_updated","")
				oXMLDoc.DocumentElement.AppendChild(oTextNode)
			End If
			oTextNode.Text = Year(Now()) & PadZ(Month(Now()),2) & PadZ(Day(Now()),2) & "|" & PadZ(Hour(Now()),2) & ":" & PadZ(Minute(Now()),2) & ":" & PadZ(Second(Now()),2)
			
			Set oTextNode = oXMLDoc.DocumentElement.SelectSingleNode("last_updated_by")
			If oTextNode Is Nothing Then
				Set oTextNode = oXMLDoc.CreateNode(1,"last_updated_by","")
				oXMLDoc.DocumentElement.AppendChild(oTextNode)
			End If
			oTextNode.Text = sModifiedBy		
			
			oXMLDoc.Save sXMLFile
            
            Response.write WriteResponse(0)			                
            
            'Update the index for that record.
			If ReIndexRDBMOnUpdate = True Then
				sFileList = CreateIndexFileList(sFullPath & vbNewLine)
				'UpdatePartialIndex RDBM_INDEX_FOLDER, sFileList
				UpdateIndex RDBM_INDEX_FOLDER
			End If
        ' Also no sort..
        
     
End Function

Open in new window

>>the problem is that I would never able to fix the node here
>>Set oNode = oXMLDoc.DocumentElement.selectSingleNode("//record/book")
>>Because the same script is also been used to update

But you can do:
'obtain reference to node you want to update
Set oNode = oXMLDoc.DocumentElement.selectSingleNode("//record/ehaus/eh_feature")
' update the value to Y
oNode.text="Y"
'create new node
Set dynamicNode = oXMLDoc.createElement("eh_last_modified")
'add value to new node
dynamicNode.text="today"
'append it to ehaus node via the parent of eh_feature
oNode.parentNode.appendChild(dynamicNode)
>>Is there any way I can give you double points
No. The maximum is 500 and an A grade. You could open a different problem, but see if my previous suggestion helps you out. I believe that is what you are after.
Hielo,

will this Set dynamicNode = oXMLDoc.createElement("eh_last_modified") be created under

//record/ehaus/

or would i need to specify

Set dynamicNode = oXMLDoc.createElement("//record/ehaus/eh_last_modified")
ok thanks

can we not set selectsinglenode to something like dynamic, so that any other node from ehaus/ should be able to use it  please...
 Set featureNode = oXMLDoc.DocumentElement.selectSingleNode("//record/ehaus/eh_feature") 
            featureNode.text=sValue
        
        Set oUpdateNode = oXMLDoc.DocumentElement.SelectSingleNode("//record/ehaus/eh_last_updated")
        If oUpdateNode Is Nothing Then
	        Set oUpdateNode = oXMLDoc.CreateNode(1,"eh_last_updated","")
	        oXMLDoc.DocumentElement.AppendChild(oUpdateNode)
        End If
        oUpdateNode.Text = Year(Now()) & PadZ(Month(Now()),2) & PadZ(Day(Now()),2) & "|" & PadZ(Hour(Now()),2) & ":" & PadZ(Minute(Now()),2) & ":" & PadZ(Second(Now()),2)
		    
       

Open in new window

if i do this,

 Set featureNode = oXMLDoc.DocumentElement.SelectSingleNode("//record/ehaus/eh_feature")
                  If featureNode Is Nothing Then
                        Set featureNode = oXMLDoc.CreateNode(1,"//record/ehaus/eh_feature","")
                        oXMLDoc.DocumentElement.AppendChild(featureNode)
                  End If
                  featureNode.Text = sValue
i am getting an error, please advice
 <font face="Arial" size=2>
 
<p>msxml3.dll</font> <font face="Arial" size=2>error '80004005'</font>
 
<p>
 
<font face="Arial" size=2>This name may not contain the '/' character:
 
--&gt;/&lt;--/record/ehaus/eh_feature
 
</font>
 
<p>

Open in new window

and if i remove from createnode ... it is keeping adding  extra node to the root

 Set featureNode = oXMLDoc.DocumentElement.SelectSingleNode("//record/ehaus/eh_feature")
                  If featureNode Is Nothing Then
                        Set featureNode = oXMLDoc.CreateNode(1,"eh_feature","")
                        oXMLDoc.DocumentElement.AppendChild(featureNode)
                  End If
                  featureNode.Text = sValue

<ehaus>
<eh_date_loaded>20080410</eh_date_loaded>
</ehaus>
<eh_feature>Y</eh_feature>
<eh_feature>N</eh_feature>
<eh_feature>Y</eh_feature>
<eh_feature>N</eh_feature>

Open in new window

ASKER CERTIFIED SOLUTION
Avatar of hielo
hielo
Flag of Wallis and Futuna 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