Would someone be so kind as to test if this code works for you?

Would someone be so kind as to test if this code works for you?
It works for me but apparently not for other computers. I don’t know if it is due to the language of the computer.
The code reads an xml file generated by a scheduling software (Microsoft Project) and creates two hashes in the model with the task data.
This is the xml file
Test Project3.xml.zip (9.4 KB)

module Rtches
	module Functions
		extend self
		def self.loadXmlFileFromProject()
			require 'rexml/document'
			include REXML
			@model = Sketchup.active_model
			@model.start_operation("dates import", true)
			xmlfilename = UI.openpanel("Open XML File", "c:/", "XML Files|*.xml||")
			return unless xmlfilename
			xmlfile = File.new(xmlfilename)
			begin
				xmldoc = Document.new(xmlfile)
				@fechasdict = @model.attribute_dictionary('Sketchup4D',true)
				XPath.each(xmldoc, "//Task") { |e|
					@fechasdict.set_attribute 'Tareas',e.elements["GUID"].text,[e.elements["Name"].text,
						e.elements["Start"].text,e.elements["Finish"].text,e.elements["WBS"].text,
						e.elements["ID"].text,e.elements["Summary"].text]
					valuetoadd = e.elements["WBS"].text + " " + e.elements["Name"].text
					@fechasdict.set_attribute 'Tareas2',valuetoadd,e.elements["GUID"].text
					}
				test1 = @fechasdict.attribute_dictionary('Tareas').count
				test2 = @fechasdict.attribute_dictionary('Tareas').count
				if test1==0 || test2 ==0
					UI.messagebox('no tasks found, please check your xml file')
				else
					UI.messagebox("#{test1.to_s}"+' tasks imported')
				end
			rescue
				# mistake message
				UI.messagebox('the file could not be imported, please check the file content.')
			end
			@model.commit_operation
		end
	end
end
Rtches::Functions::loadXmlFileFromProject()

The result is this:

Thanks in advance.

The XML file is UTF-8 encoded. This is good, but often Microsoft programs on Windows produce files encoded as UTF-16LE.

The file I uploaded was the one which it’s supposed to fail with the code I posted. If the problem is the encoding it must fail in all computers, mustn’t it?

Well the default encoding for SketchUp should be UTF-8, but an extension could change this. (We hope not though.)

I haven’t yet tried the code. I do see that you use File.new instead of File.open and a block which would automatically close the file after use. Any particular reason why?

Preliminary results:

Ran the code on a new empty model. … it said “13 tasks created”.

After getting the newer Attribute Inspector properly installed I do see the 13 tasks in the 2 subdictionaries.

Win10 SketchUp 22.0


I did a little cleanup …
(1) The bailout clause should always go before you start an operation, otherwise there will be a operation left open.
(2) Wrapped the file object in the block form of File.open
(3) … added an encoding: 'UTF-8:UTF-8' argument to tell the method that the file is UTF-8 encoded and the internal encoding is the same.
(4) Added an ensure clause to close the file object in case of an error.

EDIT:
(5) Added a statement in the rescue clause to send the exception to the console.

module Rtches
  module Functions
    extend self
    def self.loadXmlFileFromProject()
      xmlfilename = UI.openpanel("Open XML File", "c:/", "XML Files|*.xml||")
      return unless xmlfilename
      #
      require 'rexml/document' unless defined?(::REXML)
      include ::REXML
      #
      @model = Sketchup.active_model
      @model.start_operation("dates import", true)
      #
      ###
        #
        File.open(xmlfilename, encoding: 'UTF-8:UTF-8') do |xmlfile|
          xmldoc = Document.new(xmlfile)
          @fechasdict = @model.attribute_dictionary('Sketchup4D',true)
          XPath.each(xmldoc, "//Task") { |e|
            @fechasdict.set_attribute 'Tareas',e.elements["GUID"].text,[e.elements["Name"].text,
              e.elements["Start"].text,e.elements["Finish"].text,e.elements["WBS"].text,
              e.elements["ID"].text,e.elements["Summary"].text]
            valuetoadd = e.elements["WBS"].text + " " + e.elements["Name"].text
            @fechasdict.set_attribute 'Tareas2',valuetoadd,e.elements["GUID"].text
            }
          test1 = @fechasdict.attribute_dictionary('Tareas').count
          test2 = @fechasdict.attribute_dictionary('Tareas2').count
          if test1==0 || test2 ==0
            UI.messagebox('no tasks found, please check your xml file')
          else
            UI.messagebox("#{test1.to_s}"+' tasks imported')
          end
        rescue => error
          puts error.inspect
          # mistake message
          UI.messagebox('the file could not be imported, please check the file content.')
        ensure
          xmlfile.close
        end
        #
      ###
      #
      @model.commit_operation
    end
  end
end
1 Like

Is there any error shown of these “non-working” computers ?

There is no special reason. I should have it in previous script

It does not show any error because it jumps directly to the rescue section.
The only thing that may be happening is that the model they are working on shows that it is read-only.
Could the error be due to the fact that it is read-only and cannot execute part of the code?

Thank you very much for your suggestions, they help me to improve.

EDITED the above snippet …
(5) Added a statement in the rescue clause to send the exception to the console.

[ I didn’t notice that it was suppressing all errors before. ]

Could be (if on Mac) as adding attribute dictionaries an attribute values modifies the model.

On Windows, I can open a read-only model to modify and SaveAs into a new file with a different name. So we should not get an error until a Save is attempted. (Manually this happens by showing a messagebox with a “Try again with a different filename” message.)

You might be able to detect that the open file is read only,…
File.writable?(@model.path)
… and if not, force as SaveCopyAs.

1 Like