Bug(バグ) #1300 » XML_Util-1.2.3_to_1.3.0.diff
XML/Util.php | ||
---|---|---|
<?php
|
||
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
|
||
/**
|
||
* XML_Util
|
||
*
|
||
... | ... | |
*/
|
||
/**
|
||
* error code for invalid chars in XML name
|
||
* Error code for invalid chars in XML name
|
||
*/
|
||
define('XML_UTIL_ERROR_INVALID_CHARS', 51);
|
||
/**
|
||
* error code for invalid chars in XML name
|
||
* Error code for invalid chars in XML name
|
||
*/
|
||
define('XML_UTIL_ERROR_INVALID_START', 52);
|
||
/**
|
||
* error code for non-scalar tag content
|
||
* Error code for non-scalar tag content
|
||
*/
|
||
define('XML_UTIL_ERROR_NON_SCALAR_CONTENT', 60);
|
||
/**
|
||
* error code for missing tag name
|
||
* Error code for missing tag name
|
||
*/
|
||
define('XML_UTIL_ERROR_NO_TAG_NAME', 61);
|
||
/**
|
||
* replace XML entities
|
||
* Replace XML entities
|
||
*/
|
||
define('XML_UTIL_REPLACE_ENTITIES', 1);
|
||
/**
|
||
* embedd content in a CData Section
|
||
* Embedd content in a CData Section
|
||
*/
|
||
define('XML_UTIL_CDATA_SECTION', 5);
|
||
/**
|
||
* do not replace entitites
|
||
* Do not replace entitites
|
||
*/
|
||
define('XML_UTIL_ENTITIES_NONE', 0);
|
||
/**
|
||
* replace all XML entitites
|
||
* Replace all XML entitites
|
||
* This setting will replace <, >, ", ' and &
|
||
*/
|
||
define('XML_UTIL_ENTITIES_XML', 1);
|
||
/**
|
||
* replace only required XML entitites
|
||
* Replace only required XML entitites
|
||
* This setting will replace <, " and &
|
||
*/
|
||
define('XML_UTIL_ENTITIES_XML_REQUIRED', 2);
|
||
/**
|
||
* replace HTML entitites
|
||
* Replace HTML entitites
|
||
* @link http://www.php.net/htmlentities
|
||
*/
|
||
define('XML_UTIL_ENTITIES_HTML', 3);
|
||
... | ... | |
define('XML_UTIL_COLLAPSE_XHTML_ONLY', 2);
|
||
/**
|
||
* utility class for working with XML documents
|
||
* Utility class for working with XML documents
|
||
*
|
||
* @category XML
|
||
* @package XML_Util
|
||
* @author Stephan Schmidt <schst@php.net>
|
||
* @copyright 2003-2008 Stephan Schmidt <schst@php.net>
|
||
* @license http://opensource.org/licenses/bsd-license New BSD License
|
||
* @version Release: 1.2.3
|
||
* @version Release: 1.3.0
|
||
* @link http://pear.php.net/package/XML_Util
|
||
*/
|
||
class XML_Util
|
||
{
|
||
/**
|
||
* return API version
|
||
* Return API version
|
||
*
|
||
* @return string $version API version
|
||
* @access public
|
||
* @static
|
||
*/
|
||
function apiVersion()
|
||
public static function apiVersion()
|
||
{
|
||
return '1.1';
|
||
}
|
||
/**
|
||
* replace XML entities
|
||
* Replace XML entities
|
||
*
|
||
* With the optional second parameter, you may select, which
|
||
* entities should be replaced.
|
||
... | ... | |
* by the htmlentities() function
|
||
*
|
||
* @return string string with replaced chars
|
||
* @access public
|
||
* @static
|
||
* @see reverseEntities()
|
||
* @see reverseEntities()
|
||
*/
|
||
function replaceEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML,
|
||
$encoding = 'ISO-8859-1')
|
||
{
|
||
public static function replaceEntities(
|
||
$string, $replaceEntities = XML_UTIL_ENTITIES_XML, $encoding = 'ISO-8859-1'
|
||
) {
|
||
switch ($replaceEntities) {
|
||
case XML_UTIL_ENTITIES_XML:
|
||
return strtr($string, array(
|
||
'&' => '&',
|
||
'>' => '>',
|
||
'<' => '<',
|
||
'"' => '"',
|
||
'\'' => ''' ));
|
||
return strtr(
|
||
$string,
|
||
array(
|
||
'&' => '&',
|
||
'>' => '>',
|
||
'<' => '<',
|
||
'"' => '"',
|
||
'\'' => '''
|
||
)
|
||
);
|
||
break;
|
||
case XML_UTIL_ENTITIES_XML_REQUIRED:
|
||
return strtr($string, array(
|
||
'&' => '&',
|
||
'<' => '<',
|
||
'"' => '"' ));
|
||
return strtr(
|
||
$string,
|
||
array(
|
||
'&' => '&',
|
||
'<' => '<',
|
||
'"' => '"'
|
||
)
|
||
);
|
||
break;
|
||
case XML_UTIL_ENTITIES_HTML:
|
||
return htmlentities($string, ENT_COMPAT, $encoding);
|
||
... | ... | |
}
|
||
/**
|
||
* reverse XML entities
|
||
* Reverse XML entities
|
||
*
|
||
* With the optional second parameter, you may select, which
|
||
* entities should be reversed.
|
||
... | ... | |
* by the html_entity_decode() function
|
||
*
|
||
* @return string string with replaced chars
|
||
* @access public
|
||
* @static
|
||
* @see replaceEntities()
|
||
* @see replaceEntities()
|
||
*/
|
||
function reverseEntities($string, $replaceEntities = XML_UTIL_ENTITIES_XML,
|
||
$encoding = 'ISO-8859-1')
|
||
{
|
||
public static function reverseEntities(
|
||
$string, $replaceEntities = XML_UTIL_ENTITIES_XML, $encoding = 'ISO-8859-1'
|
||
) {
|
||
switch ($replaceEntities) {
|
||
case XML_UTIL_ENTITIES_XML:
|
||
return strtr($string, array(
|
||
'&' => '&',
|
||
'>' => '>',
|
||
'<' => '<',
|
||
'"' => '"',
|
||
''' => '\'' ));
|
||
return strtr(
|
||
$string,
|
||
array(
|
||
'&' => '&',
|
||
'>' => '>',
|
||
'<' => '<',
|
||
'"' => '"',
|
||
''' => '\''
|
||
)
|
||
);
|
||
break;
|
||
case XML_UTIL_ENTITIES_XML_REQUIRED:
|
||
return strtr($string, array(
|
||
'&' => '&',
|
||
'<' => '<',
|
||
'"' => '"' ));
|
||
return strtr(
|
||
$string,
|
||
array(
|
||
'&' => '&',
|
||
'<' => '<',
|
||
'"' => '"'
|
||
)
|
||
);
|
||
break;
|
||
case XML_UTIL_ENTITIES_HTML:
|
||
return html_entity_decode($string, ENT_COMPAT, $encoding);
|
||
... | ... | |
}
|
||
/**
|
||
* build an xml declaration
|
||
* Build an xml declaration
|
||
*
|
||
* <code>
|
||
* require_once 'XML/Util.php';
|
||
... | ... | |
* @param bool $standalone document is standalone (or not)
|
||
*
|
||
* @return string xml declaration
|
||
* @access public
|
||
* @static
|
||
* @uses attributesToString() to serialize the attributes of the XML declaration
|
||
* @uses attributesToString() to serialize the attributes of the
|
||
* XML declaration
|
||
*/
|
||
function getXMLDeclaration($version = '1.0', $encoding = null,
|
||
$standalone = null)
|
||
{
|
||
public static function getXMLDeclaration(
|
||
$version = '1.0', $encoding = null, $standalone = null
|
||
) {
|
||
$attributes = array(
|
||
'version' => $version,
|
||
);
|
||
... | ... | |
$attributes['standalone'] = $standalone ? 'yes' : 'no';
|
||
}
|
||
return sprintf('<?xml%s?>',
|
||
XML_Util::attributesToString($attributes, false));
|
||
return sprintf(
|
||
'<?xml%s?>',
|
||
XML_Util::attributesToString($attributes, false)
|
||
);
|
||
}
|
||
/**
|
||
* build a document type declaration
|
||
* Build a document type declaration
|
||
*
|
||
* <code>
|
||
* require_once 'XML/Util.php';
|
||
... | ... | |
* @param string $internalDtd internal dtd entries
|
||
*
|
||
* @return string doctype declaration
|
||
* @access public
|
||
* @static
|
||
* @since 0.2
|
||
* @since 0.2
|
||
*/
|
||
function getDocTypeDeclaration($root, $uri = null, $internalDtd = null)
|
||
{
|
||
public static function getDocTypeDeclaration(
|
||
$root, $uri = null, $internalDtd = null
|
||
) {
|
||
if (is_array($uri)) {
|
||
$ref = sprintf(' PUBLIC "%s" "%s"', $uri['id'], $uri['uri']);
|
||
} elseif (!empty($uri)) {
|
||
... | ... | |
}
|
||
/**
|
||
* create string representation of an attribute list
|
||
* Create string representation of an attribute list
|
||
*
|
||
* <code>
|
||
* require_once 'XML/Util.php';
|
||
... | ... | |
* XML_UTIL_ENTITIES_HTML)
|
||
*
|
||
* @return string string representation of the attributes
|
||
* @access public
|
||
* @static
|
||
* @uses replaceEntities() to replace XML entities in attribute values
|
||
* @todo allow sort also to be an options array
|
||
* @uses replaceEntities() to replace XML entities in attribute values
|
||
* @todo allow sort also to be an options array
|
||
*/
|
||
function attributesToString($attributes, $sort = true, $multiline = false,
|
||
$indent = ' ', $linebreak = "\n", $entities = XML_UTIL_ENTITIES_XML)
|
||
{
|
||
public static function attributesToString(
|
||
$attributes, $sort = true, $multiline = false,
|
||
$indent = ' ', $linebreak = "\n", $entities = XML_UTIL_ENTITIES_XML
|
||
) {
|
||
/*
|
||
* second parameter may be an array
|
||
*/
|
||
... | ... | |
if ($sort) {
|
||
ksort($attributes);
|
||
}
|
||
if ( !$multiline || count($attributes) == 1) {
|
||
if (!$multiline || count($attributes) == 1) {
|
||
foreach ($attributes as $key => $value) {
|
||
if ($entities != XML_UTIL_ENTITIES_NONE) {
|
||
if ($entities === XML_UTIL_CDATA_SECTION) {
|
||
... | ... | |
* or only XHTML (XML_UTIL_COLLAPSE_XHTML_ONLY) ones.
|
||
*
|
||
* @return string XML
|
||
* @access public
|
||
* @static
|
||
* @todo PEAR CS - unable to avoid "space after open parens" error
|
||
* in the IF branch
|
||
*/
|
||
function collapseEmptyTags($xml, $mode = XML_UTIL_COLLAPSE_ALL)
|
||
public static function collapseEmptyTags($xml, $mode = XML_UTIL_COLLAPSE_ALL)
|
||
{
|
||
if ($mode == XML_UTIL_COLLAPSE_XHTML_ONLY) {
|
||
return preg_replace(
|
||
'/<(area|base(?:font)?|br|col|frame|hr|img|input|isindex|link|meta|'
|
||
. 'param)([^>]*)><\/\\1>/s',
|
||
'<\\1\\2 />',
|
||
$xml);
|
||
$xml
|
||
);
|
||
} else {
|
||
return preg_replace('/<(\w+)([^>]*)><\/\\1>/s', '<\\1\\2 />', $xml);
|
||
}
|
||
}
|
||
/**
|
||
* create a tag
|
||
* Create a tag
|
||
*
|
||
* This method will call XML_Util::createTagFromArray(), which
|
||
* is more flexible.
|
||
... | ... | |
* @param bool $sortAttributes Whether to sort the attributes or not
|
||
*
|
||
* @return string XML tag
|
||
* @access public
|
||
* @static
|
||
* @see createTagFromArray()
|
||
* @uses createTagFromArray() to create the tag
|
||
* @see createTagFromArray()
|
||
* @uses createTagFromArray() to create the tag
|
||
*/
|
||
function createTag($qname, $attributes = array(), $content = null,
|
||
public static function createTag(
|
||
$qname, $attributes = array(), $content = null,
|
||
$namespaceUri = null, $replaceEntities = XML_UTIL_REPLACE_ENTITIES,
|
||
$multiline = false, $indent = '_auto', $linebreak = "\n",
|
||
$sortAttributes = true)
|
||
{
|
||
$sortAttributes = true
|
||
) {
|
||
$tag = array(
|
||
'qname' => $qname,
|
||
'attributes' => $attributes
|
||
... | ... | |
$tag['namespaceUri'] = $namespaceUri;
|
||
}
|
||
return XML_Util::createTagFromArray($tag, $replaceEntities, $multiline,
|
||
$indent, $linebreak, $sortAttributes);
|
||
return XML_Util::createTagFromArray(
|
||
$tag, $replaceEntities, $multiline,
|
||
$indent, $linebreak, $sortAttributes
|
||
);
|
||
}
|
||
/**
|
||
* create a tag from an array
|
||
* this method awaits an array in the following format
|
||
* Create a tag from an array.
|
||
* This method awaits an array in the following format
|
||
* <pre>
|
||
* array(
|
||
* // qualified name of the tag
|
||
... | ... | |
* @param bool $sortAttributes Whether to sort the attributes or not
|
||
*
|
||
* @return string XML tag
|
||
* @access public
|
||
* @static
|
||
* @see createTag()
|
||
*
|
||
* @see createTag()
|
||
* @uses attributesToString() to serialize the attributes of the tag
|
||
* @uses splitQualifiedName() to get local part and namespace of a qualified name
|
||
* @uses createCDataSection()
|
||
* @uses raiseError()
|
||
*/
|
||
function createTagFromArray($tag, $replaceEntities = XML_UTIL_REPLACE_ENTITIES,
|
||
public static function createTagFromArray(
|
||
$tag, $replaceEntities = XML_UTIL_REPLACE_ENTITIES,
|
||
$multiline = false, $indent = '_auto', $linebreak = "\n",
|
||
$sortAttributes = true)
|
||
{
|
||
$sortAttributes = true
|
||
) {
|
||
if (isset($tag['content']) && !is_scalar($tag['content'])) {
|
||
return XML_Util::raiseError('Supplied non-scalar value as tag content',
|
||
XML_UTIL_ERROR_NON_SCALAR_CONTENT);
|
||
return XML_Util::raiseError(
|
||
'Supplied non-scalar value as tag content',
|
||
XML_UTIL_ERROR_NON_SCALAR_CONTENT
|
||
);
|
||
}
|
||
if (!isset($tag['qname']) && !isset($tag['localPart'])) {
|
||
return XML_Util::raiseError('You must either supply a qualified name '
|
||
return XML_Util::raiseError(
|
||
'You must either supply a qualified name '
|
||
. '(qname) or local tag name (localPart).',
|
||
XML_UTIL_ERROR_NO_TAG_NAME);
|
||
XML_UTIL_ERROR_NO_TAG_NAME
|
||
);
|
||
}
|
||
// if no attributes hav been set, use empty attributes
|
||
... | ... | |
if (isset($tag['namespaceUri']) && !empty($tag['namespaceUri'])) {
|
||
// is a namespace given
|
||
if (isset($tag['namespace']) && !empty($tag['namespace'])) {
|
||
$tag['attributes']['xmlns:' . $tag['namespace']] =
|
||
$tag['namespaceUri'];
|
||
$tag['attributes']['xmlns:' . $tag['namespace']]
|
||
= $tag['namespaceUri'];
|
||
} else {
|
||
// define this Uri as the default namespace
|
||
$tag['attributes']['xmlns'] = $tag['namespaceUri'];
|
||
... | ... | |
}
|
||
// create attribute list
|
||
$attList = XML_Util::attributesToString($tag['attributes'],
|
||
$sortAttributes, $multiline, $indent, $linebreak);
|
||
$attList = XML_Util::attributesToString(
|
||
$tag['attributes'],
|
||
$sortAttributes, $multiline, $indent, $linebreak
|
||
);
|
||
if (!isset($tag['content']) || (string)$tag['content'] == '') {
|
||
$tag = sprintf('<%s%s />', $tag['qname'], $attList);
|
||
} else {
|
||
... | ... | |
$tag['content'] = XML_Util::createCDataSection($tag['content']);
|
||
break;
|
||
default:
|
||
$tag['content'] = XML_Util::replaceEntities($tag['content'],
|
||
$replaceEntities);
|
||
$tag['content'] = XML_Util::replaceEntities(
|
||
$tag['content'], $replaceEntities
|
||
);
|
||
break;
|
||
}
|
||
$tag = sprintf('<%s%s>%s</%s>', $tag['qname'], $attList, $tag['content'],
|
||
$tag['qname']);
|
||
$tag = sprintf(
|
||
'<%s%s>%s</%s>', $tag['qname'], $attList, $tag['content'],
|
||
$tag['qname']
|
||
);
|
||
}
|
||
return $tag;
|
||
}
|
||
/**
|
||
* create a start element
|
||
* Create a start element
|
||
*
|
||
* <code>
|
||
* require_once 'XML/Util.php';
|
||
... | ... | |
* @param bool $sortAttributes Whether to sort the attributes or not
|
||
*
|
||
* @return string XML start element
|
||
* @access public
|
||
* @static
|
||
* @see createEndElement(), createTag()
|
||
* @see createEndElement(), createTag()
|
||
*/
|
||
function createStartElement($qname, $attributes = array(), $namespaceUri = null,
|
||
public static function createStartElement(
|
||
$qname, $attributes = array(), $namespaceUri = null,
|
||
$multiline = false, $indent = '_auto', $linebreak = "\n",
|
||
$sortAttributes = true)
|
||
{
|
||
$sortAttributes = true
|
||
) {
|
||
// if no attributes hav been set, use empty attributes
|
||
if (!isset($attributes) || !is_array($attributes)) {
|
||
$attributes = array();
|
||
... | ... | |
}
|
||
// create attribute list
|
||
$attList = XML_Util::attributesToString($attributes, $sortAttributes,
|
||
$multiline, $indent, $linebreak);
|
||
$attList = XML_Util::attributesToString(
|
||
$attributes, $sortAttributes,
|
||
$multiline, $indent, $linebreak
|
||
);
|
||
$element = sprintf('<%s%s>', $qname, $attList);
|
||
return $element;
|
||
}
|
||
/**
|
||
* create an end element
|
||
* Create an end element
|
||
*
|
||
* <code>
|
||
* require_once 'XML/Util.php';
|
||
... | ... | |
* @param string $qname qualified tagname (including namespace)
|
||
*
|
||
* @return string XML end element
|
||
* @access public
|
||
* @static
|
||
* @see createStartElement(), createTag()
|
||
* @see createStartElement(), createTag()
|
||
*/
|
||
function createEndElement($qname)
|
||
public static function createEndElement($qname)
|
||
{
|
||
$element = sprintf('</%s>', $qname);
|
||
return $element;
|
||
}
|
||
/**
|
||
* create an XML comment
|
||
* Create an XML comment
|
||
*
|
||
* <code>
|
||
* require_once 'XML/Util.php';
|
||
... | ... | |
* @param string $content content of the comment
|
||
*
|
||
* @return string XML comment
|
||
* @access public
|
||
* @static
|
||
*/
|
||
function createComment($content)
|
||
public static function createComment($content)
|
||
{
|
||
$comment = sprintf('<!-- %s -->', $content);
|
||
return $comment;
|
||
}
|
||
/**
|
||
* create a CData section
|
||
* Create a CData section
|
||
*
|
||
* <code>
|
||
* require_once 'XML/Util.php';
|
||
... | ... | |
* @param string $data data of the CData section
|
||
*
|
||
* @return string CData section with content
|
||
* @access public
|
||
* @static
|
||
*/
|
||
function createCDataSection($data)
|
||
public static function createCDataSection($data)
|
||
{
|
||
return sprintf('<![CDATA[%s]]>',
|
||
preg_replace('/\]\]>/', ']]]]><![CDATA[>', strval($data)));
|
||
return sprintf(
|
||
'<![CDATA[%s]]>',
|
||
preg_replace('/\]\]>/', ']]]]><![CDATA[>', strval($data))
|
||
);
|
||
}
|
||
/**
|
||
* split qualified name and return namespace and local part
|
||
* Split qualified name and return namespace and local part
|
||
*
|
||
* <code>
|
||
* require_once 'XML/Util.php';
|
||
... | ... | |
* @param string $defaultNs default namespace (optional)
|
||
*
|
||
* @return array array containing namespace and local part
|
||
* @access public
|
||
* @static
|
||
*/
|
||
function splitQualifiedName($qname, $defaultNs = null)
|
||
public static function splitQualifiedName($qname, $defaultNs = null)
|
||
{
|
||
if (strstr($qname, ':')) {
|
||
$tmp = explode(':', $qname);
|
||
... | ... | |
}
|
||
/**
|
||
* check, whether string is valid XML name
|
||
* Check, whether string is valid XML name
|
||
*
|
||
* <p>XML names are used for tagname, attribute names and various
|
||
* other, lesser known entities.</p>
|
||
... | ... | |
* @param string $string string that should be checked
|
||
*
|
||
* @return mixed true, if string is a valid XML name, PEAR error otherwise
|
||
* @access public
|
||
* @static
|
||
*
|
||
* @todo support for other charsets
|
||
* @todo PEAR CS - unable to avoid 85-char limit on second preg_match
|
||
*/
|
||
function isValidName($string)
|
||
public static function isValidName($string)
|
||
{
|
||
// check for invalid chars
|
||
if (!preg_match('/^[[:alpha:]_]\\z/', $string{0})) {
|
||
return XML_Util::raiseError('XML names may only start with letter '
|
||
. 'or underscore', XML_UTIL_ERROR_INVALID_START);
|
||
return XML_Util::raiseError(
|
||
'XML names may only start with letter or underscore',
|
||
XML_UTIL_ERROR_INVALID_START
|
||
);
|
||
}
|
||
// check for invalid chars
|
||
if (!preg_match('/^([[:alpha:]_]([[:alnum:]\-\.]*)?:)?[[:alpha:]_]([[:alnum:]\_\-\.]+)?\\z/',
|
||
$string)
|
||
) {
|
||
return XML_Util::raiseError('XML names may only contain alphanumeric '
|
||
$match = preg_match(
|
||
'/^([[:alpha:]_]([[:alnum:]\-\.]*)?:)?'
|
||
. '[[:alpha:]_]([[:alnum:]\_\-\.]+)?\\z/',
|
||
$string
|
||
);
|
||
if (!$match) {
|
||
return XML_Util::raiseError(
|
||
'XML names may only contain alphanumeric '
|
||
. 'chars, period, hyphen, colon and underscores',
|
||
XML_UTIL_ERROR_INVALID_CHARS);
|
||
XML_UTIL_ERROR_INVALID_CHARS
|
||
);
|
||
}
|
||
// XML name is valid
|
||
return true;
|
||
}
|
||
/**
|
||
* replacement for XML_Util::raiseError
|
||
* Replacement for XML_Util::raiseError
|
||
*
|
||
* Avoids the necessity to always require
|
||
* PEAR.php
|
||
... | ... | |
* @param int $code error code
|
||
*
|
||
* @return PEAR_Error
|
||
* @access public
|
||
* @static
|
||
* @todo PEAR CS - should this use include_once instead?
|
||
* @todo PEAR CS - should this use include_once instead?
|
||
*/
|
||
function raiseError($msg, $code)
|
||
public static function raiseError($msg, $code)
|
||
{
|
||
require_once 'PEAR.php';
|
||
include_once 'PEAR.php';
|
||
return PEAR::raiseError($msg, $code);
|
||
}
|
||
}
|