Improved namespace handling: now shows shortest syntax for attributes and

elements in current namespace.
This commit is contained in:
Rowan Collins 2012-10-14 00:58:00 +01:00
parent 6ba4a27275
commit 4233dc8a6d

View file

@ -45,7 +45,7 @@ function simplexml_tree(SimpleXMLElement $sxml, $include_attributes_and_content=
{ {
// To what namespace does this attribute belong? Returns array( alias => URI ) // To what namespace does this attribute belong? Returns array( alias => URI )
$ns = $root_item->getNamespaces(false); $ns = $root_item->getNamespaces(false);
if ( $ns ) if ( key($ns) )
{ {
$dump .= key($ns) . ':'; $dump .= key($ns) . ':';
} }
@ -58,7 +58,7 @@ function simplexml_tree(SimpleXMLElement $sxml, $include_attributes_and_content=
// Display the root node as an XML tag // Display the root node as an XML tag
// To what namespace does this attribute belong? Returns array( alias => URI ) // To what namespace does this attribute belong? Returns array( alias => URI )
$ns = $root_item->getNamespaces(false); $ns = $root_item->getNamespaces(false);
if ( $ns ) if ( key($ns) )
{ {
$root_node_name = key($ns) . ':' . $root_item->getName(); $root_node_name = key($ns) . ':' . $root_item->getName();
} }
@ -118,6 +118,13 @@ function _simplexml_tree_recursively_process_node($item, $depth, $include_attrib
} }
} }
// To what namespace does this element belong? Returns array( alias => URI )
$item_ns = $item->getNamespaces(false);
if ( ! $item_ns )
{
$item_ns = array('' => NULL);
}
// This returns all namespaces used by this node and all its descendants, // This returns all namespaces used by this node and all its descendants,
// whether declared in this node, in its ancestors, or in its descendants // whether declared in this node, in its ancestors, or in its descendants
$all_ns = $item->getNamespaces(true); $all_ns = $item->getNamespaces(true);
@ -127,33 +134,25 @@ function _simplexml_tree_recursively_process_node($item, $depth, $include_attrib
$all_ns[''] = NULL; $all_ns[''] = NULL;
} }
// Prioritise "current" namespace by merging into onto the beginning of the list
// (it will be added to the beginning and the duplicate entry dropped)
$all_ns = array_merge($item_ns, $all_ns);
foreach ( $all_ns as $ns_alias => $ns_uri ) foreach ( $all_ns as $ns_alias => $ns_uri )
{ {
$children = $item->children($ns_uri); $children = $item->children($ns_alias, true);
$attributes = $item->attributes($ns_uri); $attributes = $item->attributes($ns_alias, true);
// Somewhat confusingly, in the case where a parent element is missing the xmlns declaration, // If things are in the current namespace, display them a bit differently
// but a descendant adds it, SimpleXML will look ahead and fill $all_ns[''] incorrectly $is_current_namespace = ( $ns_uri == reset($item_ns) );
if (
$ns_alias == ''
&&
! is_null($ns_uri)
&&
count($children) == 0
&&
count($attributes) == 0
)
{
// Try looking for a default namespace without a known URI
$ns_uri = NULL;
$children = $item->children($ns_uri);
$attributes = $item->attributes($ns_uri);
}
if ( count($attributes) > 0 && $include_attributes_and_content ) if ( count($attributes) > 0 && $include_attributes_and_content )
{
if ( ! $is_current_namespace )
{ {
$dump .= str_repeat($indent, $depth) $dump .= str_repeat($indent, $depth)
. "->attributes('$ns_alias', true)" . PHP_EOL; . "->attributes('$ns_alias', true)" . PHP_EOL;
}
foreach ( $attributes as $sx_attribute ) foreach ( $attributes as $sx_attribute )
{ {
@ -168,18 +167,39 @@ function _simplexml_tree_recursively_process_node($item, $depth, $include_attrib
} }
// Output the attribute // Output the attribute
// e.g. ->attribName (3 chars): 'foo' if ( $is_current_namespace )
$dump .= str_repeat($indent, $depth+1) {
. '->' . $item->getName() // In current namespace
// e.g. ['attribName'] (3 chars): 'foo'
$dump .= str_repeat($indent, $depth)
. "['" . $sx_attribute->getName() . "']"
. ' (' . strlen($string_content) . ' chars): ' . ' (' . strlen($string_content) . ' chars): '
. "'$string_extract'" . PHP_EOL; . "'$string_extract'" . PHP_EOL;
} }
else
{
// After a call to ->attributes()
// e.g. ->attribName (3 chars): 'foo'
$dump .= str_repeat($indent, $depth+1)
. '->' . $sx_attribute->getName()
. ' (' . strlen($string_content) . ' chars): '
. "'$string_extract'" . PHP_EOL;
}
}
} }
if ( count($children) > 0 ) if ( count($children) > 0 )
{
if ( $is_current_namespace )
{
$display_depth = $depth;
}
else
{ {
$dump .= str_repeat($indent, $depth) $dump .= str_repeat($indent, $depth)
. "->children('$ns_alias', true)" . PHP_EOL; . "->children('$ns_alias', true)" . PHP_EOL;
$display_depth = $depth + 1;
}
// Recurse through the children with headers showing how to access them // Recurse through the children with headers showing how to access them
$child_names = array(); $child_names = array();
@ -198,13 +218,13 @@ function _simplexml_tree_recursively_process_node($item, $depth, $include_attrib
} }
// e.g. ->Foo[0] // e.g. ->Foo[0]
$dump .= str_repeat($indent, $depth+1) $dump .= str_repeat($indent, $display_depth)
. '->' . $item->getName() . '->' . $sx_child->getName()
. '[' . $child_names[$child_node_name]-1 . ']' . '[' . ($child_names[$child_node_name]-1) . ']'
. PHP_EOL; . PHP_EOL;
$dump .= _simplexml_tree_recursively_process_node( $dump .= _simplexml_tree_recursively_process_node(
$sx_child, $depth+2, $sx_child, $display_depth+1,
$include_attributes_and_content, $indent, $content_extract_size $include_attributes_and_content, $indent, $content_extract_size
); );
} }