sbol-data-io-RDF/src/main/java/org/sbolstandard/core/io/rdf/RdfIo.java
public IoReader<QName> createIoReader(final XMLStreamReader xmlReader) throws XMLStreamException
  {
    return new IoReader<QName>() {

      @Override
      public DocumentRoot<QName> read () throws CoreIoException
      {
        try {
          while (xmlReader.hasNext())
          {
            int eventType = xmlReader.next();
            switch (eventType) {
              case  XMLEvent.START_ELEMENT:
                NamespaceBindings bindings = readBindings();
                Datatree.TopLevelDocuments<QName> topLevelDocuments= readTopLevelDocuments();
                return Datatree.DocumentRoot(bindings, topLevelDocuments);
            }
          }
        } catch (XMLStreamException e) {
          throw new CoreIoException(e);
        }
        return null;
      }

      private Datatree.NamespaceBindings readBindings() throws XMLStreamException {
        NamespaceBinding[] bindings = new NamespaceBinding[xmlReader.getNamespaceCount()];

        for(int i = 0; i < xmlReader.getNamespaceCount(); i++) {
          bindings[i] = Datatree.NamespaceBinding(xmlReader.getNamespaceURI(i), xmlReader.getNamespacePrefix(i));
        }
        return Datatree.NamespaceBindings(bindings);
      }

      /**
       * Used to store documents and properties when reading XML in the readTopLevelDocuments method
       */
      private Stack<Object> documentStack=new Stack<Object>() ;
      
      /**
       * Used to store the TopLevelDocument objects in the readTopLevelDocuments method
       */
      private List<TopLevelDocument<QName>> topLevelDocuments=null;

      /**
       * Reads RDF document and returns TopLevelDocuments.
       *
       * <p>
       * Properties and
       * documents are stored in a Stack object and populated as more data
       * become available The stack object holds one TopLevelDocument at a
       * time. Once a TopLevelDocument is read it is added to the
       * topLevelDocuments collection. For triples within a
       * TopLevelDocument the following rules apply:
       * </p>
       * Starting tags:
       * <p>
       * If a triple contains rdf:about attribute it is assumed that the
       * tag is the start of a NestedDocument. An empty Nested document is
       * added to the stack.
       * If a triple contains rdf:resource, a NamedProperty with a URI
       * value is created and added to the stack.
       * Otherwise a NamedProperty without a value is added to the stack
       * </p>
       *
       * End tags:
       * <p>
       * For each end tag, an object is taken from the stack.
       * If the object is a property The property is removed from the
       * stack The XML value (if the value exists) is used to set the
       * value of that property. The property is then added to the recent
       * document in the stack. This document can be a NestedDocument or a
       * TopLevelDocument.
       * If the object is a NestedDocument, the document is removed from
       * the stack. The property identifying the document in this case is
       * the most recent object in the stack and it is also removed from
       * the stack. The NestedDocument is then added to the parent
       * document (it can be a another NestedDocument or a
       * TopLevelDocument using the property relationship. This parent
       * document is the most recent object after removing the property.
       * If the object is TopLevelDocument, the object is removed from the
       * stack and added to the topLevelDocuments collection
       * </p>
       *
       * @return
       * @throws XMLStreamException
       */
      private Datatree.TopLevelDocuments<QName> readTopLevelDocuments()
              throws XMLStreamException {
    	  
        //Used as a buffer to read XML characters in the readTopLevelDocuments method         
        StringBuilder currentText=null;
          
    	topLevelDocuments = new ArrayList<TopLevelDocument<QName>>();
        while (xmlReader.hasNext()) {

          int eventType = xmlReader.next();
          switch (eventType) {
            case XMLEvent.START_ELEMENT:
              currentText = new StringBuilder(256);
              QName elementURI = Datatree.QName(xmlReader.getNamespaceURI(), xmlReader.getLocalName(), xmlReader.getPrefix());
              addToStack(elementURI);
              break;
            case XMLEvent.END_ELEMENT:
              String literalValue = null;
              if (currentText != null) {
                literalValue = currentText.toString();
                currentText = null;
              }
              updateDocumentInStack(literalValue);
              break;
            case XMLEvent.CHARACTERS:
              String characters = xmlReader.getText();
              if (currentText != null) {
                currentText.append(characters);
              }
              break;
          }
        }
        Datatree.TopLevelDocuments<QName> documents = Datatree
                .TopLevelDocuments(topLevelDocuments.toArray(new TopLevelDocument[topLevelDocuments.size()]));
        return documents;
        // return Datatree.<QName> TopLevelDocuments();
      }

      private void addToStack(QName elementURI) throws XMLStreamException
      {
        URI identity = null;
        URI resourceURI = null;

        int attributes = xmlReader.getAttributeCount();
        for (int i = 0; i < attributes; ++i)
        {
          if (rdfAbout.getLocalPart().equals(xmlReader.getAttributeLocalName(i)) && rdfAbout.getNamespaceURI().equals(xmlReader.getAttributeNamespace(i)))            
          {
            identity = URI.create(xmlReader.getAttributeValue(i));
          }
          if (rdfResource.getLocalPart().equals(xmlReader.getAttributeLocalName(i)) && rdfResource.getNamespaceURI().equals(xmlReader.getAttributeNamespace(i)))
          {
            resourceURI = URI.create(xmlReader.getAttributeValue(i));
          }
        }

        if (identity != null)
        {
          Datatree.NamespaceBindings bindings = readBindings();
          IdentifiableDocument<QName> document = null;
          if (documentStack.isEmpty())
          {
            document = Datatree.TopLevelDocument(bindings, elementURI, identity);
          }
          else
          {
            document = Datatree.NestedDocument(bindings, elementURI, identity);
          }
          documentStack.push(document);
        }
        else
        {
          NamedProperty<QName> property = null;
          if (resourceURI != null)
          {
            property = Datatree.NamedProperty(elementURI, resourceURI);
          }
          else
          {
            // TODO Make sure this is ok. The value type is not known yet!
            property = Datatree.NamedProperty(elementURI, "");
          }
          documentStack.push(property);
        }
      }


      private void updateDocumentInStack(String literalValue) throws XMLStreamException
      {
        // Get the object in the stack
        if (!documentStack.isEmpty())
        {
          Object stackObject = documentStack.pop();

          if (stackObject instanceof NamedProperty)
          {
            NamedProperty<QName> property = (NamedProperty<QName>) stackObject;
            // Set its property value
            if (literalValue != null && literalValue.length() > 0)
            {
              property = Datatree.NamedProperty(property.getName(), literalValue);
            }
            updateDocumentInStackWithProperty(property);
          }
          else if (stackObject instanceof NestedDocument)
          {
            NestedDocument<QName> document = (NestedDocument<QName>) stackObject;

            // Get the property for the nested document
            NamedProperty<QName> property = (NamedProperty<QName>) documentStack
                    .pop();
            property = Datatree.NamedProperty(property.getName(), document);
            updateDocumentInStackWithProperty(property);

            // Skip the ending of the property tag. The nested
            // document is attached to the parent using the property
            // already.
            while (xmlReader.hasNext())
            {
              int eventType = xmlReader.next();

              if (eventType == XMLEvent.END_ELEMENT)
              {
                String elementURI = xmlReader.getNamespaceURI() + xmlReader.getLocalName();
                if (elementURI.equals(property.getName().getNamespaceURI() + property.getName().getLocalPart()))
                {
                  break;
                }
              }
            }
          }
          else if (stackObject instanceof TopLevelDocument)
          {
            topLevelDocuments.add((TopLevelDocument<QName>) stackObject);
          }
        }
      }

      private void updateDocumentInStackWithProperty(NamedProperty<QName> property)
      {
        //Add it to the document in the stack
        IdentifiableDocument<QName> documentInStack=(IdentifiableDocument<QName>)documentStack.pop();
        documentInStack=addProperty(documentInStack, property);

        //Put the document back to the stack
        documentStack.push(documentInStack);
      }

      private IdentifiableDocument<QName> addProperty(
              IdentifiableDocument<QName> document, NamedProperty<QName> property)
      {

        List<NamedProperty<QName>> properties = new ArrayList<>();
        if (document.getProperties() == null || document.getProperties().size() == 0)
        {
          properties = Datatree.NamedProperties(property).getProperties();
        }
        else
        {
          properties.addAll(document.getProperties());
          // TODO if the Property value is a NestedDocument then add
          // the property using the same property key, still works without this though!
          properties.add(property);
        }
        NamedProperty<QName>[] propertyArray = properties.toArray(new NamedProperty[properties.size()]);
        NamedProperties<QName> namedProperties = Datatree.NamedProperties(propertyArray);
        NamespaceBindings bindings = Datatree.NamespaceBindings(
                (NamespaceBinding[]) document.getNamespaceBindings().toArray(new NamespaceBinding[document.getNamespaceBindings().size()]));

        if (document instanceof TopLevelDocument)
        {
          document = Datatree.TopLevelDocument(bindings,
                  document.getType(),
                  document.getIdentity(),
                  namedProperties);
        }
        else
        {
          document = Datatree.NestedDocument(
                  bindings,
                  document.getType(),
                  document.getIdentity(),
                  namedProperties);
        }

        return document;
      }

    };
  }
public IoReader<QName> createIoReader(final XMLStreamReader xmlReader) throws XMLStreamException
  {
    return new IoReader<QName>() {

      @Override
      public DocumentRoot<QName> read () throws CoreIoException
      {
        try {
          while (xmlReader.hasNext())
          {
            int eventType = xmlReader.next();
            switch (eventType) {
              case  XMLEvent.START_ELEMENT:
                NamespaceBindings bindings = readBindings();
                Datatree.TopLevelDocuments<QName> topLevelDocuments= readTopLevelDocuments();
                return Datatree.DocumentRoot(bindings, topLevelDocuments);
            }
          }
        } catch (XMLStreamException e) {
          throw new CoreIoException(e);
        }
        return null;
      }

      private Datatree.NamespaceBindings readBindings() throws XMLStreamException {
        NamespaceBinding[] bindings = new NamespaceBinding[xmlReader.getNamespaceCount()];

        for(int i = 0; i < xmlReader.getNamespaceCount(); i++) {
          bindings[i] = Datatree.NamespaceBinding(xmlReader.getNamespaceURI(i), xmlReader.getNamespacePrefix(i));
        }
        return Datatree.NamespaceBindings(bindings);
      }

      /**
       * Used to store documents and properties when reading XML in the readTopLevelDocuments method
       */
      private Stack<Object> documentStack=new Stack<Object>() ;
      
      /**
       * Used to store the TopLevelDocument objects in the readTopLevelDocuments method
       */
      private List<TopLevelDocument<QName>> topLevelDocuments=null;

      /**
       * Reads RDF document and returns TopLevelDocuments.
       *
       * <p>
       * Properties and
       * documents are stored in a Stack object and populated as more data
       * become available The stack object holds one TopLevelDocument at a
       * time. Once a TopLevelDocument is read it is added to the
       * topLevelDocuments collection. For triples within a
       * TopLevelDocument the following rules apply:
       * </p>
       * Starting tags:
       * <p>
       * If a triple contains rdf:about attribute it is assumed that the
       * tag is the start of a NestedDocument. An empty Nested document is
       * added to the stack.
       * If a triple contains rdf:resource, a NamedProperty with a URI
       * value is created and added to the stack.
       * Otherwise a NamedProperty without a value is added to the stack
       * </p>
       *
       * End tags:
       * <p>
       * For each end tag, an object is taken from the stack.
       * If the object is a property The property is removed from the
       * stack The XML value (if the value exists) is used to set the
       * value of that property. The property is then added to the recent
       * document in the stack. This document can be a NestedDocument or a
       * TopLevelDocument.
       * If the object is a NestedDocument, the document is removed from
       * the stack. The property identifying the document in this case is
       * the most recent object in the stack and it is also removed from
       * the stack. The NestedDocument is then added to the parent
       * document (it can be a another NestedDocument or a
       * TopLevelDocument using the property relationship. This parent
       * document is the most recent object after removing the property.
       * If the object is TopLevelDocument, the object is removed from the
       * stack and added to the topLevelDocuments collection
       * </p>
       *
       * @return
       * @throws XMLStreamException
       */
      private Datatree.TopLevelDocuments<QName> readTopLevelDocuments()
              throws XMLStreamException {
    	  
        //Used as a buffer to read XML characters in the readTopLevelDocuments method         
        StringBuilder currentText=null;
          
    	topLevelDocuments = new ArrayList<TopLevelDocument<QName>>();
        while (xmlReader.hasNext()) {

          int eventType = xmlReader.next();
          switch (eventType) {
            case XMLEvent.START_ELEMENT:
              currentText = new StringBuilder(256);
              QName elementURI = Datatree.QName(xmlReader.getNamespaceURI(), xmlReader.getLocalName(), xmlReader.getPrefix());
              addToStack(elementURI);
              break;
            case XMLEvent.END_ELEMENT:
              String literalValue = null;
              if (currentText != null) {
                literalValue = currentText.toString();
                currentText = null;
              }
              updateDocumentInStack(literalValue);
              break;
            case XMLEvent.CHARACTERS:
              String characters = xmlReader.getText();
              if (currentText != null) {
                currentText.append(characters);
              }
              break;
          }
        }
        Datatree.TopLevelDocuments<QName> documents = Datatree
                .TopLevelDocuments(topLevelDocuments.toArray(new TopLevelDocument[topLevelDocuments.size()]));
        return documents;
        // return Datatree.<QName> TopLevelDocuments();
      }

      private void addToStack(QName elementURI) throws XMLStreamException
      {
        URI identity = null;
        URI resourceURI = null;

        int attributes = xmlReader.getAttributeCount();
        for (int i = 0; i < attributes; ++i)
        {
          if (rdfAbout.getLocalPart().equals(xmlReader.getAttributeLocalName(i)) && rdfAbout.getNamespaceURI().equals(xmlReader.getAttributeNamespace(i)))            
          {
            identity = URI.create(xmlReader.getAttributeValue(i));
          }
          if (rdfResource.getLocalPart().equals(xmlReader.getAttributeLocalName(i)) && rdfResource.getNamespaceURI().equals(xmlReader.getAttributeNamespace(i)))
          {
            resourceURI = URI.create(xmlReader.getAttributeValue(i));
          }
        }

        if (identity != null)
        {
          Datatree.NamespaceBindings bindings = readBindings();
          IdentifiableDocument<QName> document = null;
          if (documentStack.isEmpty())
          {
            document = Datatree.TopLevelDocument(bindings, elementURI, identity);
          }
          else
          {
            document = Datatree.NestedDocument(bindings, elementURI, identity);
          }
          documentStack.push(document);
        }
        else
        {
          NamedProperty<QName> property = null;
          if (resourceURI != null)
          {
            property = Datatree.NamedProperty(elementURI, resourceURI);
          }
          else
          {
            // TODO Make sure this is ok. The value type is not known yet!
            property = Datatree.NamedProperty(elementURI, "");
          }
          documentStack.push(property);
        }
      }


      private void updateDocumentInStack(String literalValue) throws XMLStreamException
      {
        // Get the object in the stack
        if (!documentStack.isEmpty())
        {
          Object stackObject = documentStack.pop();

          if (stackObject instanceof NamedProperty)
          {
            NamedProperty<QName> property = (NamedProperty<QName>) stackObject;
            // Set its property value
            if (literalValue != null && literalValue.length() > 0)
            {
              property = Datatree.NamedProperty(property.getName(), literalValue);
            }
            updateDocumentInStackWithProperty(property);
          }
          else if (stackObject instanceof NestedDocument)
          {
            NestedDocument<QName> document = (NestedDocument<QName>) stackObject;

            // Get the property for the nested document
            NamedProperty<QName> property = (NamedProperty<QName>) documentStack
                    .pop();
            property = Datatree.NamedProperty(property.getName(), document);
            updateDocumentInStackWithProperty(property);

            // Skip the ending of the property tag. The nested
            // document is attached to the parent using the property
            // already.
            while (xmlReader.hasNext())
            {
              int eventType = xmlReader.next();

              if (eventType == XMLEvent.END_ELEMENT)
              {
                String elementURI = xmlReader.getNamespaceURI() + xmlReader.getLocalName();
                if (elementURI.equals(property.getName().getNamespaceURI() + property.getName().getLocalPart()))
                {
                  break;
                }
              }
            }
          }
          else if (stackObject instanceof TopLevelDocument)
          {
            topLevelDocuments.add((TopLevelDocument<QName>) stackObject);
          }
        }
      }

      private void updateDocumentInStackWithProperty(NamedProperty<QName> property)
      {
        //Add it to the document in the stack
        IdentifiableDocument<QName> documentInStack=(IdentifiableDocument<QName>)documentStack.pop();
        documentInStack=addProperty(documentInStack, property);

        //Put the document back to the stack
        documentStack.push(documentInStack);
      }

      private IdentifiableDocument<QName> addProperty(
              IdentifiableDocument<QName> document, NamedProperty<QName> property)
      {

        List<NamedProperty<QName>> properties = new ArrayList<>();
        if (document.getProperties() == null || document.getProperties().size() == 0)
        {
          properties = Datatree.NamedProperties(property).getProperties();
        }
        else
        {
          properties.addAll(document.getProperties());
          // TODO if the Property value is a NestedDocument then add
          // the property using the same property key, still works without this though!
          properties.add(property);
        }
        NamedProperty<QName>[] propertyArray = properties.toArray(new NamedProperty[properties.size()]);
        NamedProperties<QName> namedProperties = Datatree.NamedProperties(propertyArray);
        NamespaceBindings bindings = Datatree.NamespaceBindings(
                (NamespaceBinding[]) document.getNamespaceBindings().toArray(new NamespaceBinding[document.getNamespaceBindings().size()]));

        if (document instanceof TopLevelDocument)
        {
          document = Datatree.TopLevelDocument(bindings,
                  document.getType(),
                  document.getIdentity(),
                  namedProperties);
        }
        else
        {
          document = Datatree.NestedDocument(
                  bindings,
                  document.getType(),
                  document.getIdentity(),
                  namedProperties);
        }

        return document;
      }

    };
  }
public IoReader < QName > createIoReader ( final XMLStreamReader xmlReader ) throws XMLStreamException { return new IoReader < QName > ( ) { @ Override public DocumentRoot < QName > read ( ) throws CoreIoException { try { while ( xmlReader . hasNext ( ) ) { int eventType = xmlReader . next ( ) ; switch ( eventType ) { case XMLEvent . START_ELEMENT : NamespaceBindings bindings = readBindings ( ) ; Datatree . TopLevelDocuments < QName > topLevelDocuments = readTopLevelDocuments ( ) ; return Datatree . DocumentRoot ( bindings , topLevelDocuments ) ; } } } catch ( XMLStreamException e ) { throw new CoreIoException ( e ) ; } return null ; } private Datatree . NamespaceBindings readBindings ( ) throws XMLStreamException { NamespaceBinding [ ] bindings = new NamespaceBinding [ xmlReader . getNamespaceCount ( ) ] ; for ( int i = 0 ; i < xmlReader . getNamespaceCount ( ) ; i ++ ) { bindings [ i ] = Datatree . NamespaceBinding ( xmlReader . getNamespaceURI ( i ) , xmlReader . getNamespacePrefix ( i ) ) ; } return Datatree . NamespaceBindings ( bindings ) ; } /**
       * Used to store documents and properties when reading XML in the readTopLevelDocuments method
       */ private Stack < Object > documentStack = new Stack < Object > ( ) ; /**
       * Used to store the TopLevelDocument objects in the readTopLevelDocuments method
       */ private List < TopLevelDocument < QName > > topLevelDocuments = null ; /**
       * Reads RDF document and returns TopLevelDocuments.
       *
       * <p>
       * Properties and
       * documents are stored in a Stack object and populated as more data
       * become available The stack object holds one TopLevelDocument at a
       * time. Once a TopLevelDocument is read it is added to the
       * topLevelDocuments collection. For triples within a
       * TopLevelDocument the following rules apply:
       * </p>
       * Starting tags:
       * <p>
       * If a triple contains rdf:about attribute it is assumed that the
       * tag is the start of a NestedDocument. An empty Nested document is
       * added to the stack.
       * If a triple contains rdf:resource, a NamedProperty with a URI
       * value is created and added to the stack.
       * Otherwise a NamedProperty without a value is added to the stack
       * </p>
       *
       * End tags:
       * <p>
       * For each end tag, an object is taken from the stack.
       * If the object is a property The property is removed from the
       * stack The XML value (if the value exists) is used to set the
       * value of that property. The property is then added to the recent
       * document in the stack. This document can be a NestedDocument or a
       * TopLevelDocument.
       * If the object is a NestedDocument, the document is removed from
       * the stack. The property identifying the document in this case is
       * the most recent object in the stack and it is also removed from
       * the stack. The NestedDocument is then added to the parent
       * document (it can be a another NestedDocument or a
       * TopLevelDocument using the property relationship. This parent
       * document is the most recent object after removing the property.
       * If the object is TopLevelDocument, the object is removed from the
       * stack and added to the topLevelDocuments collection
       * </p>
       *
       * @return
       * @throws XMLStreamException
       */ private Datatree . TopLevelDocuments < QName > readTopLevelDocuments ( ) throws XMLStreamException { //Used as a buffer to read XML characters in the readTopLevelDocuments method         
 StringBuilder currentText = null ; topLevelDocuments = new ArrayList < TopLevelDocument < QName > > ( ) ; while ( xmlReader . hasNext ( ) ) { int eventType = xmlReader . next ( ) ; switch ( eventType ) { case XMLEvent . START_ELEMENT : currentText = new StringBuilder ( 256 ) ; QName elementURI = Datatree . QName ( xmlReader . getNamespaceURI ( ) , xmlReader . getLocalName ( ) , xmlReader . getPrefix ( ) ) ; addToStack ( elementURI ) ; break ; case XMLEvent . END_ELEMENT : String literalValue = null ; if ( currentText != null ) { literalValue = currentText . toString ( ) ; currentText = null ; } updateDocumentInStack ( literalValue ) ; break ; case XMLEvent . CHARACTERS : String characters = xmlReader . getText ( ) ; if ( currentText != null ) { currentText . append ( characters ) ; } break ; } } Datatree . TopLevelDocuments < QName > documents = Datatree . TopLevelDocuments ( topLevelDocuments . toArray ( new TopLevelDocument [ topLevelDocuments . size ( ) ] ) ) ; return documents ; // return Datatree.<QName> TopLevelDocuments();
 } private void addToStack ( QName elementURI ) throws XMLStreamException { URI identity = null ; URI resourceURI = null ; int attributes = xmlReader . getAttributeCount ( ) ; for ( int i = 0 ; i < attributes ; ++ i ) { if ( rdfAbout . getLocalPart ( ) . equals ( xmlReader . getAttributeLocalName ( i ) ) && rdfAbout . getNamespaceURI ( ) . equals ( xmlReader . getAttributeNamespace ( i ) ) ) { identity = URI . create ( xmlReader . getAttributeValue ( i ) ) ; } if ( rdfResource . getLocalPart ( ) . equals ( xmlReader . getAttributeLocalName ( i ) ) && rdfResource . getNamespaceURI ( ) . equals ( xmlReader . getAttributeNamespace ( i ) ) ) { resourceURI = URI . create ( xmlReader . getAttributeValue ( i ) ) ; } } if ( identity != null ) { Datatree . NamespaceBindings bindings = readBindings ( ) ; IdentifiableDocument < QName > document = null ; if ( documentStack . isEmpty ( ) ) { document = Datatree . TopLevelDocument ( bindings , elementURI , identity ) ; } else { document = Datatree . NestedDocument ( bindings , elementURI , identity ) ; } documentStack . push ( document ) ; } else { NamedProperty < QName > property = null ; if ( resourceURI != null ) { property = Datatree . NamedProperty ( elementURI , resourceURI ) ; } else { // TODO Make sure this is ok. The value type is not known yet!
 property = Datatree . NamedProperty ( elementURI , "" ) ; } documentStack . push ( property ) ; } } private void updateDocumentInStack ( String literalValue ) throws XMLStreamException { // Get the object in the stack
 if ( ! documentStack . isEmpty ( ) ) { Object stackObject = documentStack . pop ( ) ; if ( stackObject instanceof NamedProperty ) { NamedProperty < QName > property = ( NamedProperty < QName > ) stackObject ; // Set its property value
 if ( literalValue != null && literalValue . length ( ) > 0 ) { property = Datatree . NamedProperty ( property . getName ( ) , literalValue ) ; } updateDocumentInStackWithProperty ( property ) ; } else if ( stackObject instanceof NestedDocument ) { NestedDocument < QName > document = ( NestedDocument < QName > ) stackObject ; // Get the property for the nested document
 NamedProperty < QName > property = ( NamedProperty < QName > ) documentStack . pop ( ) ; property = Datatree . NamedProperty ( property . getName ( ) , document ) ; updateDocumentInStackWithProperty ( property ) ; // Skip the ending of the property tag. The nested
 // document is attached to the parent using the property
 // already.
 while ( xmlReader . hasNext ( ) ) { int eventType = xmlReader . next ( ) ; if ( eventType == XMLEvent . END_ELEMENT ) { String elementURI = xmlReader . getNamespaceURI ( ) + xmlReader . getLocalName ( ) ; if ( elementURI . equals ( property . getName ( ) . getNamespaceURI ( ) + property . getName ( ) . getLocalPart ( ) ) ) { break ; } } } } else if ( stackObject instanceof TopLevelDocument ) { topLevelDocuments . add ( ( TopLevelDocument < QName > ) stackObject ) ; } } } private void updateDocumentInStackWithProperty ( NamedProperty < QName > property ) { //Add it to the document in the stack
 IdentifiableDocument < QName > documentInStack = ( IdentifiableDocument < QName > ) documentStack . pop ( ) ; documentInStack = addProperty ( documentInStack , property ) ; //Put the document back to the stack
 documentStack . push ( documentInStack ) ; } private IdentifiableDocument < QName > addProperty ( IdentifiableDocument < QName > document , NamedProperty < QName > property ) { List < NamedProperty < QName >> properties = new ArrayList <> ( ) ; if ( document . getProperties ( ) == null || document . getProperties ( ) . size ( ) == 0 ) { properties = Datatree . NamedProperties ( property ) . getProperties ( ) ; } else { properties . addAll ( document . getProperties ( ) ) ; // TODO if the Property value is a NestedDocument then add
 // the property using the same property key, still works without this though!
 properties . add ( property ) ; } NamedProperty < QName > [ ] propertyArray = properties . toArray ( new NamedProperty [ properties . size ( ) ] ) ; NamedProperties < QName > namedProperties = Datatree . NamedProperties ( propertyArray ) ; NamespaceBindings bindings = Datatree . NamespaceBindings ( ( NamespaceBinding [ ] ) document . getNamespaceBindings ( ) . toArray ( new NamespaceBinding [ document . getNamespaceBindings ( ) . size ( ) ] ) ) ; if ( document instanceof TopLevelDocument ) { document = Datatree . TopLevelDocument ( bindings , document . getType ( ) , document . getIdentity ( ) , namedProperties ) ; } else { document = Datatree . NestedDocument ( bindings , document . getType ( ) , document . getIdentity ( ) , namedProperties ) ; } return document ; } } ; }
Creates an {@link IoReader} using the given {@link XMLStreamReader}.
<p>
This {@link IoReader} provides a method to read data in RDF/XML format and deserialise it into a {@link DocumentRoot} object.
</p>
@param xmlReader The {@link XMLStreamReader} reader to read RDF/XML data.
@return {@link IoReader}
@throws XMLStreamException  when the underlying reader raises an exception
Creates an {