14 Replies Latest reply on Jun 30, 2011 8:53 AM by robomd

    Modifying value in external xml file

    robomd Level 1

      Hi,

       

      I've been searching around for some time and haven't been able to find the solution to what I think should be a simple problem.

      I have an xml file that I need to change the value of an item from False to True.

       

      The structure of the file is:

      <data>

      <system-page>

      <id>1</id>

      <other fields></other fields>

      <dynamic-metadata>

           <name>publish</name>

           <name>yes</name>

      </dynamic-metadata>

      <dynamic-metadata>

           <name>frontpage</name>

           <name>no</name>

      </dynamic-metadata>

      </system-page>

      <!---tons more system pages--->

      </data>

       

      I am able to read the file and get to the exact line as such:

      <cffile action="read" file="E:\test.xml" variable="newsFile" charset="utf-8"/>
      <cfset newsXML=XmlParse(newsFile)/>
      <cfset arrItemNodes = XmlSearch(newsFile,"/data/system-page[@id='1']/dynamic-metadata[name='frontpage']/value")/>   
      

       

      I'm not sure how to edit and save the value. I imaging it's something like this:

      <cfset arrItemNodes[1].xmlText = 'True'>
      

       


      But is there anyway to save this information in the xml file at the right location?

       

      Any help is appreciated.

        • 1. Re: Modifying value in external xml file
          -==cfSearching==- Level 4
          I'm not sure how to edit and save the value. I imaging it's something like this:
          <cfset arrItemNodes[1].xmlText = 'True'>
          

          I have not actually tested it, but your logic sounds right.  So give it a whirl. Just use ToString( ...) to convert the xml document back into a string. Then save it to disk.

           

          http://help.adobe.com/en_US/ColdFusion/9.0/Developing/WSc3ff6d0ea77859461172e0811cbec133ba -7ff6.html#WSc3ff6d0ea77859461172e0811cbec133ba-7fde

          1 person found this helpful
          • 2. Re: Modifying value in external xml file
            robomd Level 1

            Thanks for the quick response. That's helpful, but how would I use ToString to only replace the corresponding section within the XML file and not replace then entire file with only that section. I have the following:

             

            <cfset XMLText=ToString(arrItemNodes)> 
            <cffile action="write" file="E:\test.xml" output="#XMLText#">
            

             

             

            But this gives me an error.

            I also tried ToString(newsXML) but this is essentially just copying the file back in without making any edits.

            • 3. Re: Modifying value in external xml file
              -==cfSearching==- Level 4

              Exactly what code did you use and what was the full error message? Also are you on CF8 or 9?

               

              My thinking was "arrItemNodes" should be a reference. So assuming you a) have the correct node and b) can modify it (I did not test it), any changes should be reflected in the root xml document as well. Then you could ToString(newsXML).

              • 4. Re: Modifying value in external xml file
                robomd Level 1

                 

                 

                Error occured on page http://test.cfm File: E:\test.cfm Complex object types cannot be converted to simple values. The expression has requested a variable or an intermediate expression result as a simple value. However, the result cannot be converted to a simple value. Simple values are strings, numbers, boolean values, and date/time values. Queries, arrays, and COM objects are examples of complex values.

                 

                The most likely cause of the error is that you tried to use a complex value as a simple one. For example, you tried to use a query variable in a cfif tag.
                The error occurred on line 13.

                 


                 

                11:     <cfset arrItemNodes[1].xmlText = 'True'>
                12:     
                13:     <cfset XMLText=ToString(arrItemNodes)> 
                14:     <cffile action="write" file="E:\test.xml" output="#XMLText#">


                Is it because I'm sending in an array? I don't see how the write action would know where to embed my edit in the XML file.

                 

                Not sure which CF version, I think 8? Obviously I'm new to CF. I appreciate the help.

                • 5. Re: Modifying value in external xml file
                  -==cfSearching==- Level 4
                  Is it because I'm sending in an array?

                   

                   

                  Yes.  If you check the documentation  linked above, it explains the function expects an "a simple value such as an integer, a binary object, or an XML document". An array is not any of those types. So that is why you are getting the error. You need to pass in the whole xml document.

                   

                   

                   

                  I don't see how the write action would know where to embed my edit in the XML file.

                   

                  Correct. It would not know. You need to write the entire xml document back to the file (ie xmlText).

                   

                   

                  Not sure which CF version, I think 8? Obviously I'm new to CF.

                   

                   

                  Welcome to CF. You can find out your server version by cfdumping the SERVER scope.  Cfdump is a great debugging tool.  Also, if you are new be sure to bookmark the online documentation.  It is my first stop when I have questions about a function or tag. Still use it most every day :-)

                   

                  ie      <cfdump var="#server#">

                   

                  Message was edited by: -==cfSearching==-

                  • 6. Re: Modifying value in external xml file
                    -==cfSearching==- Level 4

                    BTW: You may want to double check your

                    XmlSearch expression too. I suspect it may not return the correct node. 
                    • 7. Re: Modifying value in external xml file
                      robomd Level 1

                      Correct. It would not know. You need to write the entire xml document back to the file (ie xmlText).

                       

                      Is there a simple way to copy an XML file and incorporate the change.

                       

                      For example, (this gives an error) why can't I do something similar to this?

                       

                      <cffile action="read" file="E:\test.xml" variable="newsFile" charset="utf-8"/>

                      <cfset newsXML=XmlParse(newsFile)/>

                      <cfset newsXML.data.systempage[@id='1'].dynamic-metadata[name='frontpage'].value.xmlText = 'True'>

                      <cffile action="write" file="E:\test.xml" output="#XMLText#">--->

                      • 8. Re: Modifying value in external xml file
                        -==cfSearching==- Level 4
                        this gives an error

                         

                        When you encounter an error always post the error message ;-)  Otherwise we have no way of knowing what the problem is .. Not everyone has the time (or even access to a CF server) to test your code and try and figure it out.

                         

                        Is there a simple way to copy an XML file and incorporate the change.

                         

                        Like I said you should be able to do exactly that.  But I also included a lot caveats, which you may have missed like :" ... assuming you a) have the correct node and b) can modify it ... ".  Right now I am not sure either of those are true in your environment.  So first things first

                         

                        1) What is the error message

                        2) Verify you have the correct node using CFDUMP

                        • 9. Re: Modifying value in external xml file
                          robomd Level 1

                          500 - Internal server error.

                          There is a problem with the resource you are looking for, and it cannot be displayed.


                          Sorry I know it's not of much help. I don't have access to the server logs to see exactly what the problem is.

                          The variable is right. I had a typo in my original post. The xml looks like this:

                          <dynamic-metadata>

                               <name>publish</name>

                               <value>yes</value>

                          </dynamic-metadata>

                          <dynamic-metadata>

                               <name>frontpage</name>

                               <value>no</value>

                          </dynamic-metadata>

                           

                          I really appreciate the help. I've spent the past day googling around to get this far.

                          • 10. Re: Modifying value in external xml file
                            -==cfSearching==- Level 4
                            I don't have access to the server logs to see exactly what the problem is.

                             

                            Well that is also good to know.  I often assume people have full server access and do not suggest alternatives like cftry/cfcatch  ;-)   Are you able to use cfdump to see your CF version? It is sometimes disabled on shared hosting.

                             

                            /data/system-page[@id='1']/dynamic-metadata[name='frontpage']/value

                             

                            I am not an xpath guru. But I am not convinced you are actually retrieving the correct node ... which may be causing your error.  May want to double check your expression. This site has a great xpath intro .

                             

                            Anyway, if you try both of these, what are the results?

                             

                                <cfset node = XmlSearch(newsXML, "/data/system-page[@id='1']/dynamic-metadata[name='frontpage']/value")>

                                <cfdump var="#node#" label="original expression">

                                <cfset node = XmlSearch(newsXML, "/data/system-page[id='1']/dynamic-metadata[name='frontpage']/value")>

                                <cfdump var="#node#" label="new expression">

                             

                            Message was edited by: -==cfSearching==-

                             

                            Message was edited by: -==cfSearching==-

                            • 11. Re: Modifying value in external xml file
                              robomd Level 1

                              I'm seeing this:

                               

                              array
                              1
                              xml element
                              XmlNamevalue
                              XmlNsPrefix
                              XmlNsURI
                              XmlTextFalse
                              XmlComment
                              XmlAttributes
                              struct [empty]
                              XmlChildren

                               

                               

                              It looks like the right one. I guess I would need to copy the XML file into a ColdFusion XML object and then edit the value and finally write it out as an xml file. I thought that my code was doing that but I think there might be something else I'm missing.

                              • 12. Re: Modifying value in external xml file
                                -==cfSearching==- Level 4

                                Which xmlSearch expression did you use (see previous post)? I think you used the corrected one and that is why you are no longer getting an error.

                                 

                                    ie    <cfset nodeArray = XmlSearch(newsXML, "/data/system-page[id='1']/dynamic-metadata[name='frontpage']/value") >

                                 

                                Since it works, go ahead and update the xmlText of the first node in the results

                                 

                                       <cfset nodeArray[1] = "whatever you want here">

                                 

                                Then convert the entire document back to a string

                                 

                                        <cfset xmlText = ToString( newsXML )>

                                 

                                Finally write that stringto your file

                                 

                                       <cffile action="write" file="E:\test.xml" output="#XMLText#">

                                 

                                Message was edited by: -==cfSearching==-

                                1 person found this helpful
                                • 13. Re: Modifying value in external xml file
                                  robomd Level 1

                                  I just found out that my issue is a little deeper. The XML is getting republished from a CMS. I'll have to go into the CMS and edit the file in there. Thank you for your patience and help though.

                                  • 14. Re: Modifying value in external xml file
                                    -==cfSearching==- Level 4

                                    Haha. Well if you ever need to do this in the future, now you know how ;-)


                                    Cheers