diff --git a/src/main/java/it/inaf/oats/vospace/datamodel/NodeTypeJsonResolver.java b/src/main/java/it/inaf/oats/vospace/datamodel/NodeTypeJsonResolver.java
index de05ac5277648800d4d3e4029099e85ba05d9ced..bd53002bd70f6cbf7e0621ec05b82e547edfbf76 100644
--- a/src/main/java/it/inaf/oats/vospace/datamodel/NodeTypeJsonResolver.java
+++ b/src/main/java/it/inaf/oats/vospace/datamodel/NodeTypeJsonResolver.java
@@ -28,7 +28,7 @@ public class NodeTypeJsonResolver extends TypeIdResolverBase {
     @Override
     public String idFromValue(Object o) {
         Node node = (Node) o;
-        return node.getType();
+        return "vos:" + node.getClass().getSimpleName();
     }
 
     @Override
diff --git a/src/main/java/net/ivoa/xml/uws/v1/JobSummary.java b/src/main/java/net/ivoa/xml/uws/v1/JobSummary.java
index 1f21455a86d930564380cf5bed31542cecd7d4cb..64dac435a553e2d86be5452ed2805be509e437fd 100644
--- a/src/main/java/net/ivoa/xml/uws/v1/JobSummary.java
+++ b/src/main/java/net/ivoa/xml/uws/v1/JobSummary.java
@@ -94,8 +94,10 @@ import org.w3c.dom.Element;
     "errorSummary",
     "jobInfo"
 })
+// <edit>
 @XmlSeeAlso({Transfer.class}) // Necessary for setting a Transfer inside the jobInfo property.
 @XmlRootElement(name = "job")
+// </edit>
 public class JobSummary {
 
     @XmlElement(required = true)
@@ -510,8 +512,10 @@ public class JobSummary {
     @XmlType(name = "", propOrder = {
         "any"
     })
+    // <edit>
     @JsonSerialize(using = JobInfoSerializer.class)
     @JsonDeserialize(using = JobInfoDeserializer.class)
+    // </edit>
     public static class JobInfo {
 
         @XmlAnyElement(lax = true)
diff --git a/src/main/java/net/ivoa/xml/uws/v1/package-info.java b/src/main/java/net/ivoa/xml/uws/v1/package-info.java
index f0848139a7ede580de7a1298e6f58938e4b335b4..9146854a8eaeca3edca3e0c1b0c221469d1e2acc 100644
--- a/src/main/java/net/ivoa/xml/uws/v1/package-info.java
+++ b/src/main/java/net/ivoa/xml/uws/v1/package-info.java
@@ -8,13 +8,19 @@
 @javax.xml.bind.annotation.XmlSchema(
         namespace = "http://www.ivoa.net/xml/UWS/v1.0",
         elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
+        // <edit>
         // Defining the namespace prefix is necessary otherwise
         // deserialized XML will have no prefixes
         xmlns = {
             @javax.xml.bind.annotation.XmlNs(
                     namespaceURI = "http://www.ivoa.net/xml/UWS/v1.0",
                     prefix = "uws"
+            ),
+            @javax.xml.bind.annotation.XmlNs(
+                    namespaceURI = "http://www.w3.org/2001/XMLSchema-instance",
+                    prefix = "xsi"
             )
         }
+        // </edit>
 )
 package net.ivoa.xml.uws.v1;
diff --git a/src/main/java/net/ivoa/xml/vospace/v2/ContainerNode.java b/src/main/java/net/ivoa/xml/vospace/v2/ContainerNode.java
index b53c3cad8ed780eb7a509d5bcdc3c5dd290b1963..88a6e56f79bd3aa6f2b2f748cf5a31def38dec9a 100644
--- a/src/main/java/net/ivoa/xml/vospace/v2/ContainerNode.java
+++ b/src/main/java/net/ivoa/xml/vospace/v2/ContainerNode.java
@@ -56,8 +56,10 @@ import javax.xml.bind.annotation.XmlType;
 @XmlType(name = "ContainerNode", propOrder = {
     "nodes"
 })
+// <edit>
 @XmlRootElement(name = "node")
 @JsonDeserialize(converter = NodeTypeSetter.ContainerNode.class)
+// </edit>
 public class ContainerNode
     extends DataNode
 {
diff --git a/src/main/java/net/ivoa/xml/vospace/v2/LinkNode.java b/src/main/java/net/ivoa/xml/vospace/v2/LinkNode.java
index 031f1026814e5855c5ef387bb70d04a238194824..0ca6e3e6bd8624add102c8f4480865b2cb0cea04 100644
--- a/src/main/java/net/ivoa/xml/vospace/v2/LinkNode.java
+++ b/src/main/java/net/ivoa/xml/vospace/v2/LinkNode.java
@@ -45,8 +45,10 @@ import javax.xml.bind.annotation.XmlType;
 @XmlType(name = "LinkNode", propOrder = {
     "target"
 })
+// <edit>
 @XmlRootElement(name = "node")
 @JsonDeserialize(converter = NodeTypeSetter.LinkNode.class)
+// </edit>
 public class LinkNode
     extends Node
 {
diff --git a/src/main/java/net/ivoa/xml/vospace/v2/Node.java b/src/main/java/net/ivoa/xml/vospace/v2/Node.java
index 622be80d0f523d8306c9bfaf69092e040d2dd9e3..25da4e9af6cc9fbd9fba85e8f8c9c11a250c5fe2 100644
--- a/src/main/java/net/ivoa/xml/vospace/v2/Node.java
+++ b/src/main/java/net/ivoa/xml/vospace/v2/Node.java
@@ -17,17 +17,14 @@ import javax.xml.bind.annotation.XmlSeeAlso;
 import javax.xml.bind.annotation.XmlType;
 
 /**
- *
- * The base class for all nodes.
- *
- *
- * <p>
- * Java class for Node complex type.
- *
- * <p>
- * The following schema fragment specifies the expected content contained within
- * this class.
- *
+ * 
+ *         The base class for all nodes.
+ *       
+ * 
+ * <p>Java class for Node complex type.
+ * 
+ * <p>The following schema fragment specifies the expected content contained within this class.
+ * 
  * <pre>
  * &lt;complexType name="Node">
  *   &lt;complexContent>
@@ -40,8 +37,8 @@ import javax.xml.bind.annotation.XmlType;
  *   &lt;/complexContent>
  * &lt;/complexType>
  * </pre>
- *
- *
+ * 
+ * 
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "Node", propOrder = {
@@ -51,23 +48,27 @@ import javax.xml.bind.annotation.XmlType;
     LinkNode.class,
     DataNode.class
 })
+// <edit>
 @JsonTypeInfo(use = JsonTypeInfo.Id.CUSTOM, property = "type", include = JsonTypeInfo.As.EXISTING_PROPERTY)
 @JsonTypeIdResolver(NodeTypeJsonResolver.class)
+// </edit>
 public class Node {
 
     protected PropertyList properties;
 
-    // Added by Soni to manage inhetitance 
+    // <edit>
+    // Needed for handling inheritance in JSON (for XML is is automatically generated by JAXB).
     @XmlAttribute(name = "type", namespace = "http://www.w3.org/2001/XMLSchema-instance")
     protected String type;
 
     public String getType() {
-        return type;
+        return "vos:" + getClass().getSimpleName();
     }
 
     public void setType(String type) {
         this.type = type;
     }
+    // </edit>
 
     @XmlAttribute(name = "uri", required = true)
     @XmlSchemaType(name = "anyURI")
diff --git a/src/main/java/net/ivoa/xml/vospace/v2/StructuredDataNode.java b/src/main/java/net/ivoa/xml/vospace/v2/StructuredDataNode.java
index fa4c2a9bc523535232c800da1a20e362d357c4a2..71922f503d626b24953724bb58c223493fa21ee2 100644
--- a/src/main/java/net/ivoa/xml/vospace/v2/StructuredDataNode.java
+++ b/src/main/java/net/ivoa/xml/vospace/v2/StructuredDataNode.java
@@ -40,8 +40,10 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "StructuredDataNode")
+// <edit>
 @XmlRootElement(name = "node")
 @JsonDeserialize(converter = NodeTypeSetter.StructuredDataNode.class)
+// </edit>
 public class StructuredDataNode
     extends DataNode
 {
diff --git a/src/main/java/net/ivoa/xml/vospace/v2/Transfer.java b/src/main/java/net/ivoa/xml/vospace/v2/Transfer.java
index c9a392c557e62391859a9fd85cda80b7b1c2fea5..1e91484bbaab1b9140dc60775d335e25f1eedf95 100644
--- a/src/main/java/net/ivoa/xml/vospace/v2/Transfer.java
+++ b/src/main/java/net/ivoa/xml/vospace/v2/Transfer.java
@@ -71,7 +71,9 @@ import javax.xml.bind.annotation.XmlType;
     "protocol",
     "keepBytes"
 })
+// <edit>
 @XmlRootElement
+// </edit>
 public class Transfer {
 
     @XmlElement(required = true)
@@ -81,9 +83,10 @@ public class Transfer {
     protected View view;
     protected List<Protocol> protocol;
     protected Boolean keepBytes;
-    // Fix perche` manca version nel vospace.xsd
+    // <edit> Fix: version is missing in VOSpace XSD
     @XmlAttribute
     protected String version;
+    // </edit>
 
     /**
      * Gets the value of the target property.
@@ -210,6 +213,7 @@ public class Transfer {
         this.keepBytes = value;
     }
 
+    // <edit>
     public String getVersion() {
         return version;
     }
@@ -217,5 +221,6 @@ public class Transfer {
     public void setVersion(String version) {
         this.version = version;
     }
+    // </edit>
 
 }
diff --git a/src/main/java/net/ivoa/xml/vospace/v2/UnstructuredDataNode.java b/src/main/java/net/ivoa/xml/vospace/v2/UnstructuredDataNode.java
index 218f174040cac399b51739eed0c765d278e704e9..ae9256bc183a4697f48a0d44b9333aeaec23088d 100644
--- a/src/main/java/net/ivoa/xml/vospace/v2/UnstructuredDataNode.java
+++ b/src/main/java/net/ivoa/xml/vospace/v2/UnstructuredDataNode.java
@@ -40,9 +40,10 @@ import javax.xml.bind.annotation.XmlType;
  */
 @XmlAccessorType(XmlAccessType.FIELD)
 @XmlType(name = "UnstructuredDataNode")
-// added by Sonia per dirgli che puo` avere come radice un nodo singolo
-@XmlRootElement(name = "node")
+// <edit>
+@XmlRootElement(name = "node") // A single node can be the root of an XML document
 @JsonDeserialize(converter = NodeTypeSetter.UnstructuredDataNode.class)
+// <edit>
 public class UnstructuredDataNode
     extends DataNode
 {
diff --git a/src/main/java/net/ivoa/xml/vospace/v2/package-info.java b/src/main/java/net/ivoa/xml/vospace/v2/package-info.java
index 735c086b8c28e8de181b15a1b17e102c92bb77cb..65f6dfb6a2849d52175d76eacc2dbe47d4a489a2 100644
--- a/src/main/java/net/ivoa/xml/vospace/v2/package-info.java
+++ b/src/main/java/net/ivoa/xml/vospace/v2/package-info.java
@@ -7,13 +7,19 @@
 @javax.xml.bind.annotation.XmlSchema(
         namespace = "http://www.ivoa.net/xml/VOSpace/v2.0",
         elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED,
+        // <edit>
         // Defining the namespace prefix is necessary otherwise
         // deserialized XML will have no prefixes
         xmlns = {
             @javax.xml.bind.annotation.XmlNs(
                     namespaceURI = "http://www.ivoa.net/xml/VOSpace/v2.0",
                     prefix = "vos"
+            ),
+            @javax.xml.bind.annotation.XmlNs(
+                    namespaceURI = "http://www.w3.org/2001/XMLSchema-instance",
+                    prefix = "xsi"
             )
         }
+        // </edit>
 )
 package net.ivoa.xml.vospace.v2;
diff --git a/src/test/java/net/ivoa/xml/uws/v1/NodeTest.java b/src/test/java/net/ivoa/xml/uws/v1/NodeTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3f2837f808722ee136a84be3dd8a0da18270c7e6
--- /dev/null
+++ b/src/test/java/net/ivoa/xml/uws/v1/NodeTest.java
@@ -0,0 +1,154 @@
+package net.ivoa.xml.uws.v1;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.function.Function;
+import javax.xml.bind.JAXB;
+import net.ivoa.xml.vospace.v2.ContainerNode;
+import net.ivoa.xml.vospace.v2.DataNode;
+import net.ivoa.xml.vospace.v2.Node;
+import net.ivoa.xml.vospace.v2.Property;
+import net.ivoa.xml.vospace.v2.PropertyList;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import org.junit.jupiter.api.Test;
+
+public class NodeTest {
+
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
+    private static final String URI_PREFIX = "vos://example.com!vospace";
+
+    @Test
+    public void testXmlSerialization() throws Exception {
+
+        ContainerNode root = getRoot();
+
+        String xml;
+        try ( StringWriter sw = new StringWriter()) {
+            JAXB.marshal(root, sw);
+            xml = sw.toString();
+            System.out.println(xml);
+        }
+
+        assertTrue(xml.contains("<vos:node"));
+        assertTrue(xml.contains("<vos:nodes>"));
+        assertTrue(xml.contains("xsi:type=\"vos:DataNode\""));
+        assertTrue(xml.contains("xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""));
+
+        ContainerNode deserialized;
+        try ( StringReader sr = new StringReader(xml)) {
+            deserialized = JAXB.unmarshal(sr, ContainerNode.class);
+        }
+
+        verifyNodesAreEquals(root, deserialized);
+        verifyConstraints(deserialized);
+    }
+
+    @Test
+    public void testJsonSerialization() throws Exception {
+
+        ContainerNode root = getRoot();
+
+        String json = MAPPER.writeValueAsString(root);
+        System.out.println(json);
+
+        ContainerNode deserialized = MAPPER.readValue(json, ContainerNode.class);
+
+        verifyNodesAreEquals(root, deserialized);
+        verifyConstraints(deserialized);
+    }
+
+    private ContainerNode getRoot() {
+        ContainerNode root = getContainerNode("/", true, "g1", "g2");
+
+        List<Node> nodes = new ArrayList<>();
+        nodes.add(getDataNode("/node1", false, "g1", "g2", 808009979));
+        nodes.add(getDataNode("/node2", true, "g1", "g2", 305919869));
+        nodes.add(getContainerNode("/node3", true, "g1", "g2"));
+
+        ContainerNode.Nodes nodesEl = new ContainerNode.Nodes();
+        nodesEl.getNode().addAll(nodes);
+        root.setNodes(nodesEl);
+
+        return root;
+    }
+
+    private ContainerNode getContainerNode(String path, boolean isPublic, String groupRead, String groupWrite) {
+        ContainerNode node = new ContainerNode();
+        fillNode(node, path, isPublic, groupRead, groupWrite, 0);
+        return node;
+    }
+
+    private DataNode getDataNode(String path, boolean isPublic, String groupRead, String groupWrite, long size) {
+        DataNode node = new DataNode();
+        fillNode(node, path, isPublic, groupRead, groupWrite, size);
+        return node;
+    }
+
+    private void fillNode(Node node, String path, boolean isPublic, String groupRead, String groupWrite, long size) {
+
+        node.setUri(URI_PREFIX + path);
+
+        List<Property> properties = new ArrayList<>();
+
+        properties.add(createProperty("ivo://ivoa.net/vospace/core#ispublic", String.valueOf(isPublic)));
+        properties.add(createProperty("ivo://ivoa.net/vospace/core#groupread", groupRead));
+        properties.add(createProperty("ivo://ivoa.net/vospace/core#groupwrite", groupWrite));
+        properties.add(createProperty("ivo://ivoa.net/vospace/core#length", String.valueOf(size)));
+
+        PropertyList propertyList = new PropertyList();
+        propertyList.getProperty().addAll(properties);
+
+        node.setProperties(propertyList);
+    }
+
+    private Property createProperty(String uri, String value) {
+        Property prop = new Property();
+        prop.setUri(uri);
+        prop.setValue(value);
+        return prop;
+    }
+
+    private void verifyNodesAreEquals(ContainerNode serialized, ContainerNode deserialized) {
+        verifyItem(serialized, deserialized, n -> n.getType());
+        verifyItem(serialized, deserialized, n -> n.getNodes().getNode().size());
+        verifyItem(serialized, deserialized, n -> getProperty(n, "ivo://ivoa.net/vospace/core#ispublic"));
+        verifyItem(serialized, deserialized, n -> getProperty(n, "ivo://ivoa.net/vospace/core#groupread"));
+        verifyItem(serialized, deserialized, n -> getProperty(n, "ivo://ivoa.net/vospace/core#groupwrite"));
+        verifyItem(serialized, deserialized, n -> getProperty(n, "ivo://ivoa.net/vospace/core#length"));
+    }
+
+    private <T> void verifyItem(ContainerNode serialized, ContainerNode deserialized, Function<ContainerNode, T> function) {
+        assertEquals(function.apply(serialized), function.apply(deserialized));
+    }
+
+    private String getProperty(Node node, String uri) {
+        for (Property property : node.getProperties().getProperty()) {
+            if (uri.equals(property.getUri())) {
+                return property.getValue();
+            }
+        }
+        throw new IllegalArgumentException("Node doesn't contain property having uri " + uri);
+    }
+
+    private void verifyConstraints(ContainerNode deserialized) {
+        DataNode node1 = (DataNode) getChildNodeByPath(deserialized, "/node1");
+        ContainerNode node3 = (ContainerNode) getChildNodeByPath(deserialized, "/node3");
+
+        assertEquals("vos:DataNode", node1.getType());
+        assertEquals("vos:ContainerNode", node3.getType());
+    }
+
+    private Node getChildNodeByPath(ContainerNode parent, String path) {
+        for (Node node : parent.getNodes().getNode()) {
+            if ((URI_PREFIX + path).equals(node.getUri())) {
+                return node;
+            }
+        }
+        throw new IllegalArgumentException("Node not found for path " + path);
+    }
+}