/** * Import document in system view * * @param NodeInterface $parentNode * @param NamespaceRegistryInterface $ns * @param FilteredXMLReader $xml * @param int $uuidBehavior * @param array $documentNamespaces hashmap of prefix => uri for namespaces in the document */ private static function importSystemView(NodeInterface $parentNode, NamespaceRegistryInterface $ns, FilteredXMLReader $xml, $uuidBehavior, $namespaceMap = array()) { // logging echo "Adding child to ".$parentNode->getPath()."\n"; while ($xml->moveToNextAttribute()) { if ('xmlns' == $xml->prefix) { try { $prefix = $ns->getPrefix($xml->value); } catch (NamespaceException $e) { $prefix = $xml->localName; $ns->registerNamespace($prefix, $xml->value); } // @codeCoverageIgnoreStart if ('jcr' == $prefix && 'jcr' != $xml->localName) { throw new RepositoryException('Can not handle a document where the {http://www.jcp.org/jcr/1.0} namespace is not mapped to jcr'); } if ('nt' == $prefix && 'nt' != $xml->localName) { throw new RepositoryException('Can not handle a document where the {http://www.jcp.org/jcr/nt/1.0} namespace is not mapped to nt'); } // @codeCoverageIgnoreEnd $namespaceMap[$xml->localName] = $prefix; } elseif (NamespaceRegistryInterface::NAMESPACE_SV == $xml->namespaceURI && 'name' == $xml->localName) { $nodename = $xml->value; } } if (!isset($nodename)) { throw new InvalidSerializedDataException('there was no sv:name attribute in an element'); } // now get jcr:primaryType if (!$xml->read()) { throw new InvalidSerializedDataException('missing information to create node'); } if ('property' != $xml->localName || NamespaceRegistryInterface::NAMESPACE_SV != $xml->namespaceURI) { throw new InvalidSerializedDataException('first child of node must be sv:property for jcr:primaryType. Found {' . $xml->namespaceURI . '}' . $xml->localName . '="' . $xml->value . '"' . $xml->nodeType); } if (!$xml->moveToAttributeNs('name', NamespaceRegistryInterface::NAMESPACE_SV) || 'jcr:primaryType' != $xml->value) { throw new InvalidSerializedDataException('first child of node must be sv:property for jcr:primaryType. Found {' . $xml->namespaceURI . '}' . $xml->localName . '="' . $xml->value . '"'); } $xml->read(); // value child of property jcr:primaryType $xml->read(); // text content $nodetype = $xml->value; $nodename = self::cleanNamespace($nodename, $namespaceMap); $properties = array(); $xml->read(); // </value> $xml->read(); // </property> $xml->read(); // next thing // read the properties of the node. they must come first. while (XMLReader::END_ELEMENT != $xml->nodeType && 'property' == $xml->localName) { $xml->moveToAttributeNs('name', NamespaceRegistryInterface::NAMESPACE_SV); $name = $xml->value; $xml->moveToAttributeNs('type', NamespaceRegistryInterface::NAMESPACE_SV); $type = PropertyType::valueFromName($xml->value); if ($xml->moveToAttributeNs('multiple', NamespaceRegistryInterface::NAMESPACE_SV)) { $multiple = strcasecmp($xml->value, 'true') === 0; } else { $multiple = false; } $values = array(); $xml->moveToNextElement(); // go to the value child while ('value' == $xml->localName) { $xml->read(); $values[] = PropertyType::BINARY == $type ? base64_decode($xml->value) : $xml->value; $xml->read(); // </value> $xml->read(); // <value> or </property> } if (!$multiple && count($values) == 1) { $values = reset($values); // unbox if it does not need to be multivalue } $name = self::cleanNamespace($name, $namespaceMap); $properties[$name] = array('values' => $values, 'type' => $type); $xml->read(); } $node = self::addNode($parentNode, $nodename, $nodetype, $properties, $uuidBehavior); // if there are child nodes, they all come after the properties while (XMLReader::END_ELEMENT != $xml->nodeType && 'node' == $xml->localName) { self::importSystemView($node, $ns, $xml, $uuidBehavior, $namespaceMap); } if (XMLReader::END_ELEMENT != $xml->nodeType) { throw new InvalidSerializedDataException('Unexpected element in stream ' . $xml->localName . '="' . $xml->value . '"'); } $xml->read(); // </node> // logging echo "Done adding to ".$parentNode->getPath()."\n"; }