sub
new {
my
$class
=
shift
;
my
$content
=
bless
{},
$class
;
$content
->init(
@_
) or
return
$class
->error(
$content
->errstr);
$content
;
}
sub
init {
my
$content
=
shift
;
my
%param
=
@_
== 1 ? (
Body
=>
$_
[0]) :
@_
;
my
$elem
;
unless
(
$elem
=
$param
{Elem}) {
if
(LIBXML) {
my
$doc
= XML::LibXML::Document->createDocument(
'1.0'
,
'utf-8'
);
$elem
=
$doc
->createElementNS(NS,
'content'
);
$doc
->setDocumentElement(
$elem
);
}
else
{
$elem
= XML::XPath::Node::Element->new(
'content'
);
}
}
$content
->{elem} =
$elem
;
if
(
$param
{Body}) {
$content
->body(
$param
{Body});
}
if
(
$param
{Type}) {
$content
->type(
$param
{Type});
}
$content
;
}
sub
elem {
$_
[0]->{elem} }
sub
type {
my
$content
=
shift
;
if
(
@_
) {
$content
->elem->setAttribute(
'type'
,
shift
);
}
$content
->elem->getAttribute(
'type'
);
}
sub
mode {
my
$content
=
shift
;
$content
->elem->getAttribute(
'mode'
);
}
sub
body {
my
$content
=
shift
;
my
$elem
=
$content
->elem;
if
(
@_
) {
my
$data
=
shift
;
if
(LIBXML) {
$elem
->removeChildNodes;
}
else
{
$elem
->removeChild(
$_
)
for
$elem
->getChildNodes;
}
if
(
$data
=~ /[^\x09\x0a\x0d\x20-\x7f]/) {
if
(LIBXML) {
$elem
->appendChild(XML::LibXML::Text->new(encode_base64(
$data
,
''
)));
}
else
{
$elem
->appendChild(XML::XPath::Node::Text->new(encode_base64(
$data
,
''
)));
}
$elem
->setAttribute(
'mode'
,
'base64'
);
}
else
{
$data
.
'</div>'
;
my
$node
;
eval
{
if
(LIBXML) {
my
$parser
= XML::LibXML->new;
my
$tree
=
$parser
->parse_string(
$copy
);
$node
=
$tree
->getDocumentElement;
}
else
{
my
$xp
= XML::XPath->new(
xml
=>
$copy
);
$node
= ((
$xp
->find(
'/'
)->get_nodelist)[0]->getChildNodes)[0]
if
$xp
;
}
};
if
(!$@ &&
$node
) {
$elem
->appendChild(
$node
);
$elem
->setAttribute(
'mode'
,
'xml'
);
}
else
{
if
(LIBXML) {
$elem
->appendChild(XML::LibXML::Text->new(
$data
));
}
else
{
$elem
->appendChild(XML::XPath::Node::Text->new(
$data
));
}
$elem
->setAttribute(
'mode'
,
'escaped'
);
}
}
}
else
{
unless
(
exists
$content
->{__body}) {
my
$mode
=
$elem
->getAttribute(
'mode'
) ||
'xml'
;
if
(
$mode
eq
'xml'
) {
my
@children
=
grep
ref
(
$_
) =~ /Element/,
LIBXML ?
$elem
->childNodes :
$elem
->getChildNodes;
if
(
@children
) {
if
(
@children
== 1 &&
$children
[0]->getLocalName eq
'div'
) {
@children
=
LIBXML ?
$children
[0]->childNodes :
$children
[0]->getChildNodes
}
$content
->{__body} =
''
;
for
my
$n
(
@children
) {
_remove_default_ns(
$n
)
if
LIBXML;
$content
->{__body} .=
$n
->toString(LIBXML ? 1 : 0);
}
}
else
{
$content
->{__body} = LIBXML ?
$elem
->textContent :
$elem
->string_value;
}
}
elsif
(
$mode
eq
'base64'
) {
$content
->{__body} = decode_base64(LIBXML ?
$elem
->textContent :
$elem
->string_value);
}
elsif
(
$mode
eq
'escaped'
) {
$content
->{__body} = LIBXML ?
$elem
->textContent :
$elem
->string_value;
}
else
{
$content
->{__body} =
undef
;
}
if
($] >= 5.008) {
Encode::_utf8_off(
$content
->{__body});
}
}
}
$content
->{__body};
}
sub
_remove_default_ns {
my
(
$node
) =
@_
;
if
ref
(
$node
) =~ /Element$/;
for
my
$n
(
$node
->childNodes) {
_remove_default_ns(
$n
);
}
}
sub
as_xml {
my
$content
=
shift
;
if
(LIBXML) {
my
$doc
= XML::LibXML::Document->new(
'1.0'
,
'utf-8'
);
$doc
->setDocumentElement(
$content
->elem);
return
$doc
->toString(1);
}
else
{
return
$content
->elem->toString;
}
}
1;