Sunday, 15 November 2015

How to convert a matlab structure to xml file

Once a time I wanted to convert a matlab structure into an xml file. I know there are many ready solutions but I wanted one which fit exactly my needs. Let's say that we have a structure Student like this:

Student.Firstname = 'George';
Student.Surname = 'Hames';
Student.Age = 19;
Student.Semester = 'C';
Student.Course1.Grade = 8;
Student.Course2.Grade = 7;
Student.Course3.Grade = 9;
Student.Course4.Grade = 5;

and we want to convert it into this xml file:

<Student>
   <Firstname>George</Firstname>
   <Surname>Hames</Surname>
   <Age>19</Age>
   <Semester>C</Semester>
   <Course1>
      <Grade>8</Grade>
   </Course1>
   <Course2>
      <Grade>7</Grade>
   </Course2>
   <Course3>
      <Grade>9</Grade>
   </Course3>
   <Course4>
      <Grade>5</Grade>
   </Course4>
</Student>

My draft solution is this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function xml = struct2xml( s )

sfields = fieldnames(s);

xml = '';
for i=1:length(sfields)
    if isstruct(s.(sfields{i}))
            xml = [xml, strtrim(strcat('<', sfields{i}, '>')), char(10),  strtrim([struct2xml(s.(sfields{i})), strcat('</', sfields{i}, '>')]), char(10)]; 
    else
            fieldValue = s.(sfields{i});
            if (iscell(fieldValue))
                if (size(fieldValue,1)>1), fieldValue = fieldValue'; end;
                fieldValue = strjoin(fieldValue, '#');
            end
            if (isnumeric(fieldValue) && length(fieldValue)>1)
                fieldValueStr = '';
                for j=1:length(fieldValue)
                    fieldValueStr = strcat(fieldValueStr, num2str(fieldValue(j)), '#');
                end
                fieldValue = fieldValueStr(1:length(fieldValueStr)-1);
            end
            if (isnumeric(fieldValue) && length(fieldValue)==1)
                fieldValue = num2str(fieldValue);
            end
            xml = [xml, strcat('<', sfields{i}, '>', char(fieldValue), '</', sfields{i}, '>'), char(10)];
    end
end

end

First of all I have to say that it is not the optimum solution but it works for me. If a field takes multiple values, I use a delimiter (#) to represent them as a string. For example if struct1.field1 = [1 3 40 2] then in the xml we have <struct1><field1>1#3#40#2</field1></struct1>. In order to write the xml string to a file I use the following script:

1
2
3
4
5
6
7
function [] = struct2xmlfile( s, filename )
    xmlStr = struct2xml(s);
    xmlStr = strrep(xmlStr, '%', '%%');
    fid = fopen(filename, 'wt');
    fprintf(fid, xmlStr);
    fclose(fid);
end

Saturday, 5 September 2015

Embed icons in HTML select list

You can embed icons into HTML select lists by using the ddslick (http://designwithpc.com/plugins/ddslick). Let's see a practical example. Suppose that we develop a database of projects. Every project has a progress field which expresses the current status of a project. A project can be active (represented in the database with 1 and in the front-end as a green icon), stopped (represented in the database with 2 and in the front-end as a red icon) and finished (represented in the database with 3 and in the front-end as a checkmark icon). We want to build the following html select list of progress values:


The html code is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<html>
<head>
<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/jquery.ddslick.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
    $('#progressList').ddslick({ 
        onSelected: function(data) {
            $('#progress').val(data.selectedData.value);
        }
    });
});
</script>
</head>
<body>
<select id="progressList" name="progressList">
    <option value="1" data-imagesrc="images/green.png" data-description="Active project">Green</option>
    <option value="2" data-imagesrc="images/red.png" data-description="Stopped project">Red</option>
    <option value="3" data-imagesrc="images/finished.png" data-description="Completed project">Completed</option>
</select>
<input type="hidden" id="progress" value=""/>
</body>
</html>

As you can see the ddslick plugin adds two extra attributes to the html select list. The first attribute (data-imagesrc) specifies the option icon and the second attribute (data-description) the option description. You have to be careful if you want to post the list's selected value. In this case, you have to use a hidden field and update its value whenever the list's option changes.

Friday, 15 May 2015

Use psexec to execute commands on remote machines

If you want to execute a command on a remote windows system, you can use the psexec utility (https://technet.microsoft.com/en-us/sysinternals/bb897553.aspx). Download PsTools.zip, unzip it on your local hard drive and run the psexec.exe utility by using the following general syntax:
psexec \\computer-name command

Examples

Let's say that the remote machine is named test-pc. You can:
1) Get its ip configuration: psexec \\test-pc ipconfig
2) Get its shared network resources: psexec \\test-pc net view
3) Execute a program that resides on the remote system's local drive: psexec \\test-pc "C:\test\test.exe"
5) Issue any command as you would do on the local computer.

Issues

When a remote command fails to execute you can think of the following possible solutions:
1) Remember that you should have an account with the same credentials (username and password) on the remote machine.
2) Check the command's syntax. Keep in mind that paths with spaces should be enclosed in "".
3) Make sure that you have enabled the default ADMIN$ share on the remote machine.
4) Consider the possible security issues. For example, lets say that you want to change the default gateway of the remote system to 192.168.1.1. You'll need administrator privileges to do this. The psxec utility allows you to specify the username and password with which you want to execute the remote command. So, in this case you should type: psexec \\test-pc -u username -p passwd route change 0.0.0.0 mask 255.255.255.0 192.168.1.1  
 5) Even if you are an administrator on the remote machine the UAC (User Account Control) may block the command execution.Theoritically, the psexec allows you to bypass the UAC prompt by using the -h option, but in my case (Windows 8.1), this does not always work.

For more details, you should study the full documentation of psexec.