private static function importDocumentView(NodeInterface $parentNode, NamespaceRegistryInterface $ns, FilteredXMLReader $xml, $uuidBehavior, array $namespaceMap = array())
{
$nodename = $xml->name;
$properties = array();
$hasAttributes = false;
// track whether there was any xml attribute on the element to calculate depth correctly
while ($xml->moveToNextAttribute()) {
$hasAttributes = true;
if ('xmlns' === $xml->prefix) {
try {
$prefix = $ns->getPrefix($xml->value);
} catch (NamespaceException $e) {
$prefix = $xml->localName;
$ns->registerNamespace($prefix, $xml->value);
}
$namespaceMap[$xml->localName] = $prefix;
} else {
$properties[self::unescapeXmlName($xml->name, $namespaceMap)] = array('values' => $xml->value, 'type' => null);
}
}
$prefix_jcr = array_search(NamespaceRegistryInterface::PREFIX_JCR, $namespaceMap);
if (false === $prefix_jcr) {
$namespaceMap[NamespaceRegistryInterface::PREFIX_JCR] = NamespaceRegistryInterface::PREFIX_JCR;
} elseif ($prefix_jcr !== NamespaceRegistryInterface::PREFIX_JCR) {
throw new RepositoryException('Can not handle a document where the {http://www.jcp.org/jcr/1.0} namespace is not mapped to jcr');
}
$prefix_nt = array_search(NamespaceRegistryInterface::PREFIX_NT, $namespaceMap);
if (false === $prefix_nt) {
$namespaceMap[NamespaceRegistryInterface::PREFIX_NT] = NamespaceRegistryInterface::PREFIX_NT;
} elseif ($prefix_nt !== NamespaceRegistryInterface::PREFIX_NT) {
throw new RepositoryException('Can not handle a document where the {http://www.jcp.org/jcr/nt/1.0} namespace is not mapped to nt');
}
$nodename = self::unescapeXmlName($nodename, $namespaceMap);
if (isset($properties['jcr:primaryType'])) {
$type = $properties['jcr:primaryType']['values'];
unset($properties['jcr:primaryType']);
} else {
$type = 'nt:unstructured';
}
$node = self::addNode($parentNode, $nodename, $type, $properties, $uuidBehavior);
// get current depth to detect self-closing tag. unfortunately, we do
// not get an END_ELEMENT for self-closing tags but read() just jumps
// to the next element, even moving up in the tree,
$depth = $xml->depth;
if (!$hasAttributes) {
// we where on an empty element, thus not inside its attributes. change depth to 1 deeper
// thanks XMLReader, great work :-(
$depth++;
}
$xml->read();
// move out of current node to next
// TODO: what about significant whitespace? maybe the read above should not even skip significant empty whitespace...
// while we are on element and at same depth, these are children of the current node
while (XMLReader::ELEMENT === $xml->nodeType && $xml->depth === $depth) {
self::importDocumentView($node, $ns, $xml, $uuidBehavior, $namespaceMap);
}
if (XMLReader::END_ELEMENT !== $xml->nodeType && $xml->depth !== $depth - 1) {
throw new InvalidSerializedDataException('Unexpected element in stream: ' . $xml->name . '="' . $xml->value . '"');
}
if (XMLReader::END_ELEMENT === $xml->nodeType) {
$xml->read();
// end of element
}
// otherwise the previous element was self-closing and we are already on the next one
}