Ask a Question related to PERL Modules, Design and Development.
-
edward.kawas@gmail.com #1
namespace declarations in LibXML
Hi,
I am using LibXML to create an xml document. I am also using
namespaces.
The problem that i am running into is that the document that i am
creating has the namespace declaration at each element.
For instance,
<foo:A xmlns:foo="http://www.www.com/foo">
<foo:B xmlns:foo="http://www.www.com/foo"> blah blah blab </foo:B>
<foo:C xmlns:foo="http://www.www.com/foo"> blah blah blab </foo:C>
</foo:A>
And I want the following:
<foo:A xmlns:foo="http://www.www.com/foo">
<foo:B> blah blah blab </foo:B>
<foo:C> blah blah blab </foo:C>
</foo:A>
How can i achieve this?
Thanks.
Ed
edward.kawas@gmail.com Guest
-
Multiple declarations of fwLoadMenus
I am having an issue with declaring multiple fwLoadMenus. I have a template that declares a set of menus that every page uses, but I would also like... -
#39524 [Opn->Fbk]: Class declarations may not be nested
ID: 39524 Updated by: tony2001@php.net Reported By: depish at gmail dot com -Status: Open +Status: ... -
#39524 [NEW]: Class declarations may not be nested
From: depish at gmail dot com Operating system: Win XP PHP version: 5.2.0 PHP Bug Type: *Compile Issues Bug description: ... -
IPTables namespace - how to commandeer namespace
I have a Perl module, IPTables::IPv4, that I've been developing for some time, and that is in the CPAN repository. I've expanded the module to... -
[PHP-DEV] superglobals inside of function declarations
Hello, I've been using PHP for quite a while now and i'm getting interested it's internal beheaviour. I'm wondering why it isn't possible to use... -
Steven N. Hirsch #2
Re: namespace declarations in LibXML
[email]edward.kawas@gmail.com[/email] wrote:
Just a WAG, but try something like this on the top element before> Hi,
>
> I am using LibXML to create an xml document. I am also using
> namespaces.
>
> The problem that i am running into is that the document that i am
> creating has the namespace declaration at each element.
>
> For instance,
>
> <foo:A xmlns:foo="http://www.www.com/foo">
> <foo:B xmlns:foo="http://www.www.com/foo"> blah blah blab </foo:B>
> <foo:C xmlns:foo="http://www.www.com/foo"> blah blah blab </foo:C>
> </foo:A>
>
> And I want the following:
> <foo:A xmlns:foo="http://www.www.com/foo">
> <foo:B> blah blah blab </foo:B>
> <foo:C> blah blah blab </foo:C>
> </foo:A>
>
> How can i achieve this?
writing it out:
my $attr = $dom->createAttributeNS( '', 'dummy', '' );
$dom->getDocumentElement()->setAttributeNodeNS( $attr );
I solved a slightly different namespace-related problem by doing so.
Steve
Steven N. Hirsch Guest
-
edward.kawas@gmail.com #3
Re: namespace declarations in LibXML
Hi Steve, that didnt help.
Thanks.
edward.kawas@gmail.com Guest
-
Brian McCauley #4
Re: namespace declarations in LibXML
[email]edward.kawas@gmail.com[/email] wrote:Why do you care? The two are semantically identical. Are you concened> Hi,
>
> I am using LibXML to create an xml document. I am also using
> namespaces.
>
> The problem that i am running into is that the document that i am
> creating has the namespace declaration at each element.
>
> For instance,
>
> <foo:A xmlns:foo="http://www.www.com/foo">
> <foo:B xmlns:foo="http://www.www.com/foo"> blah blah blab </foo:B>
> <foo:C xmlns:foo="http://www.www.com/foo"> blah blah blab </foo:C>
> </foo:A>
>
> And I want the following:
> <foo:A xmlns:foo="http://www.www.com/foo">
> <foo:B> blah blah blab </foo:B>
> <foo:C> blah blah blab </foo:C>
> </foo:A>
about file size or the aesthetic appeal of the XML source?
I've seen similar problems myself. Perhaps if you posted a _minimal_> How can i achieve this?
but _complete_ stript that manifests the problem[1] I could advise how
to work around it.
[1] This and much other advice can be found in the posting guidelines.
Brian McCauley Guest
-
edward.kawas@gmail.com #5
Re: namespace declarations in LibXML
Hi,
I realize that they are semantically identical.
Some example code:
use XML::LibXML;
my $root =
XML::LibXML::Element->new( "A" );
$root->setNamespace( "http://www.www.com/foo", "foo" );
my $b =
XML::LibXML::Element->new( "B" );
$b->setNamespace( "http://www.www.com/foo", "foo" );
$b->setAttributeNS( "http://www.www.com/foo", "foo", "name");
$root->appendChild($b);
my $c =
XML::LibXML::Element->new( "C" );
$c->setNamespace( "http://www.www.com/foo", "foo" );
$c->setAttributeNS( "http://www.www.com/foo", "foo", "name");
$root->appendChild($c);
print $root->toString(2);
Thanks.
Ed
edward.kawas@gmail.com Guest
-
Brian McCauley #6
Re: namespace declarations in LibXML
[email]edward.kawas@gmail.com[/email] wrote:
Here you are explicitly re-inroducing the namespace in the child nodes.> Some example code:
>
> use XML::LibXML;
> my $root =
> XML::LibXML::Element->new( "A" );
> $root->setNamespace( "http://www.www.com/foo", "foo" );
>
> my $b =
> XML::LibXML::Element->new( "B" );
> $b->setNamespace( "http://www.www.com/foo", "foo" );
> $b->setAttributeNS( "http://www.www.com/foo", "foo", "name");
> $root->appendChild($b);
>
> my $c =
> XML::LibXML::Element->new( "C" );
> $c->setNamespace( "http://www.www.com/foo", "foo" );
> $c->setAttributeNS( "http://www.www.com/foo", "foo", "name");
> $root->appendChild($c);
>
> print $root->toString(2);
The simplest solution is to avoid using setAttributeNS() unless the
node has been attached to the DOM tree already so that it can inherit
namespaces.
The following will only have the namespace in the A node...
my $root = XML::LibXML::Element->new( "A" );
$root->setNamespace( "http://www.www.com/foo", "foo" );
my $b = XML::LibXML::Element->new( "B" );
$root->appendChild($b);
$b->setAttributeNS( "http://www.www.com/foo", "foo", "name");
my $c = XML::LibXML::Element->new( "C" );
$c->setAttribute( "foo:foo", "name");
$root->appendChild($c);
Brian McCauley Guest
-
edward.kawas@gmail.com #7
Re: namespace declarations in LibXML
Hi Brian,
The code you gave me results in the following:
<foo:A xmlns:foo="http://www.www.com/foo">
<B foo:foo="name"/>
<C foo:foo="name"/>
</foo:A>
The B and C elements are not prefixed.
Eddie
edward.kawas@gmail.com Guest
-
Brian McCauley #8
Re: namespace declarations in LibXML
[email]edward.kawas@gmail.com[/email] wrote:
Opps...> <foo:A xmlns:foo="http://www.www.com/foo">
> <B foo:foo="name"/>
> <C foo:foo="name"/>
> </foo:A>
> The B and C elements are not prefixed.
my $b = $root->addNewChild("http://www.www.com/foo","B" );
$b->setAttributeNS( "http://www.www.com/foo", "foo", "name");
my $c = XML::LibXML::Element->new( "foo:C" );
$c->setAttribute( "foo:foo", "name");
$root->appendChild($c);
Brian McCauley Guest
-
edward.kawas@gmail.com #9
Re: namespace declarations in LibXML
Is there any way to not hard code the namespace prefix?
Thanks,
Eddie
edward.kawas@gmail.com Guest
-
Brian McCauley #10
Re: namespace declarations in LibXML
[email]edward.kawas@gmail.com[/email] wrote:
[ no context given ]
I'm sorry I do not understand the question.> Is there any way to not hard code the namespace prefix?
Brian McCauley Guest
-
edward.kawas@gmail.com #11
Re: namespace declarations in LibXML
Hi Brian,
you hard-coded the prefix, i.e. $c->setAttribute("foo:foo", "name");
can we avoid this somehow? I did avoid it, by appending a $root->prefix
to the attribute foo.
So even if my solution to the above was correct, if I have 2 elements
and I want one of the elements to import/adopt/add the other, the
namespace declaration will appear twice, i.e.
Element 1:
<foo:A xmlns:foo="http://www.www.com/foo">
<foo:B foo:foo="name"/>
<foo:C foo:foo="name"/>
</foo:A>
Element 2:
<foo:E xmlns:foo="http://www.www.com/foo">
<foo:F foo:foo="name"/>
<foo:G foo:foo="name"/>
</foo:E>
And if element 1 imports or adds, etc, element 2, the result is:
<foo:A xmlns:foo="http://www.www.com/foo">
<B foo:foo="name"/>
<C foo:foo="name"/>
<foo:E xmlns:foo="http://www.www.com/foo">
<foo:F foo:foo="name"/>
<foo:G foo:foo="name"/>
</foo:E>
</foo:A>
I cant believe that there isnt a way to do this properly without
hardcoding prefixes, removing declarations, etc.
I did notice that if I use $root->addTextElement("blah blah"); and
$root has the namespaces declared, the node added is prefixed properly.
I tried looking for the source that does this to give me ideas, but I
couldnt find it. Do you have any suggestions?
Thanks Brian for your continued attempts at resolving my problem. I
appreciate it.
Eddie
edward.kawas@gmail.com Guest
-
edward.kawas@gmail.com #12
Re: namespace declarations in LibXML
sorry,
$root->addTextElement("blah blah");
should read:
$root->appendTextChild("D", "blah");
edward.kawas@gmail.com Guest
-
Brian McCauley #13
Re: namespace declarations in LibXML
[email]edward.kawas@gmail.com[/email] wrote:
[ No relevant context given. Please try to follow accepted conventions.
]
I did avoid it in the alternative method I showed you about three lines> you hard-coded the prefix, i.e. $c->setAttribute("foo:foo", "name");
> can we avoid this somehow?
earlier.
How does that not meet your requirements?
I have observed over the years that there is a very high correlation
between people who follow-up without including relevant conext and
people who ask questions that are (or at least appear to be) answered
in the post to which they are replying.
Brian McCauley Guest
-
edward.kawas@gmail.com #14
Re: namespace declarations in LibXML
Sorry, given the following, I looked at how $c was created:
my $b = $root->addNewChild("http://www.www.com/foo","B" );
$b->setAttributeNS( "http://www.www.com/foo", "foo", "name");
my $c = XML::LibXML::Element->new( "foo:C" );
$c->setAttribute( "foo:foo", "name");
$root->appendChild($c);
So it does indeed do what I wished. One last question. Given the
following code:
use XML::LibXML;
my $root = XML::LibXML::Element->new( "A" );
$root->setNamespace( "http://www.www.com/foo", "foo" );
my $b = $root->addNewChild("http://www.www.com/foo","B" );
$b->setAttributeNS( "http://www.www.com/foo", "att", "name");
my $c = $root->addNewChild("http://www.www.com/foo","C" );
$c->setAttributeNS( "http://www.www.com/foo", "art", "name");
print $root->toString(2);
my $root2 = XML::LibXML::Element->new( "E" );
$root2->setNamespace( "http://www.www.com/foo", "foo" );
my $F = $root2->addNewChild("http://www.www.com/foo","F" );
$F->setAttributeNS( "http://www.www.com/foo", "attf", "name");
my $g = $root2->addNewChild("http://www.www.com/foo","G" );
$g->setAttributeNS( "http://www.www.com/foo", "artg", "name");
print $root2->toString(2);
How can $root add $root2 such that the output is
<foo:A xmlns:foo="http://www.www.com/foo">
<foo:B foo:att="name"/>
<foo:C foo:art="name"/>
<foo:E> <!--no xmlns declaration-->
<foo:F foo:attf="name"/>
<foo:G foo:artg="name"/>
</foo:E>
</foo:A>
I have tried $root->appendChild($root2), $root->addChild($root2), etc.
Thanks again. You have helped a lot.
Ed
edward.kawas@gmail.com Guest
-
Brian McCauley #15
Re: namespace declarations in LibXML
[email]edward.kawas@gmail.com[/email] wrote:This is something that's bugged me a lot in the past. I've manged to> Given the following code:
> use XML::LibXML;
>
> my $root = XML::LibXML::Element->new( "A" );
> $root->setNamespace( "http://www.www.com/foo", "foo" );
>
> my $b = $root->addNewChild("http://www.www.com/foo","B" );
> $b->setAttributeNS( "http://www.www.com/foo", "att", "name");
>
> my $c = $root->addNewChild("http://www.www.com/foo","C" );
> $c->setAttributeNS( "http://www.www.com/foo", "art", "name");
> print $root->toString(2);
>
> my $root2 = XML::LibXML::Element->new( "E" );
> $root2->setNamespace( "http://www.www.com/foo", "foo" );
>
> my $F = $root2->addNewChild("http://www.www.com/foo","F" );
> $F->setAttributeNS( "http://www.www.com/foo", "attf", "name");
>
> my $g = $root2->addNewChild("http://www.www.com/foo","G" );
> $g->setAttributeNS( "http://www.www.com/foo", "artg", "name");
>
> print $root2->toString(2);
>
> How can $root add $root2 such that the output is
> <foo:A xmlns:foo="http://www.www.com/foo">
> <foo:B foo:att="name"/>
> <foo:C foo:art="name"/>
> <foo:E> <!--no xmlns declaration-->
> <foo:F foo:attf="name"/>
> <foo:G foo:artg="name"/>
> </foo:E>
> </foo:A>
>
> I have tried $root->appendChild($root2), $root->addChild($root2), etc.
work arround it to date most of the time using the approaches already
mentioned in this thread.
The rest of the time I've just put up with is. It's only cosmetic after
all.
I've always thought that XML::LibXML should have a function to strip
redundant xmlns declarations from a tree.
I've tried...
sub remove_redundant_namespace {
my $node = shift;
my $parent = $node->parentNode;
for my $ns ( $node->getNamespaces ) {
no warnings 'uninitialized';
if ($ns->name eq $parent->lookupNamespacePrefix($ns->value)) {
$node->removeChild($ns);
}
}
remove_redundant_namespace($_) for $node->childNodes;
}
....but this doesn't seem to work because
XML::LibXML::Node::removeChild() does not seem to recognise the
XML::LibXML::Namespace object as a child.
Brian McCauley Guest
-
edward.kawas@gmail.com #16
Re: namespace declarations in LibXML
Hi Brian,
I tried the following to remove the extra namespace declarations and it
did work (may not be too efficient though):
# code from above posts to create 2 separate elements and then merge
# them so that the final result is an element with 2 namespace
declarations
# that are the same
my $parser = XML::LibXML::->new();
$parser->clean_namespaces(1);
my $doc = $parser->parse_string($root->toString(2));
print $doc->toString();
Eddie
Brian McCauley wrote:> [email]edward.kawas@gmail.com[/email] wrote:>> > Given the following code:
> > use XML::LibXML;
> >
> > my $root = XML::LibXML::Element->new( "A" );
> > $root->setNamespace( "http://www.www.com/foo", "foo" );
> >
> > my $b = $root->addNewChild("http://www.www.com/foo","B" );
> > $b->setAttributeNS( "http://www.www.com/foo", "att", "name");
> >
> > my $c = $root->addNewChild("http://www.www.com/foo","C" );
> > $c->setAttributeNS( "http://www.www.com/foo", "art", "name");
> > print $root->toString(2);
> >
> > my $root2 = XML::LibXML::Element->new( "E" );
> > $root2->setNamespace( "http://www.www.com/foo", "foo" );
> >
> > my $F = $root2->addNewChild("http://www.www.com/foo","F" );
> > $F->setAttributeNS( "http://www.www.com/foo", "attf", "name");
> >
> > my $g = $root2->addNewChild("http://www.www.com/foo","G" );
> > $g->setAttributeNS( "http://www.www.com/foo", "artg", "name");
> >
> > print $root2->toString(2);
> >
> > How can $root add $root2 such that the output is
> > <foo:A xmlns:foo="http://www.www.com/foo">
> > <foo:B foo:att="name"/>
> > <foo:C foo:art="name"/>
> > <foo:E> <!--no xmlns declaration-->
> > <foo:F foo:attf="name"/>
> > <foo:G foo:artg="name"/>
> > </foo:E>
> > </foo:A>
> >
> > I have tried $root->appendChild($root2), $root->addChild($root2), etc.
> This is something that's bugged me a lot in the past. I've manged to
> work arround it to date most of the time using the approaches already
> mentioned in this thread.
>
> The rest of the time I've just put up with is. It's only cosmetic after
> all.
>
> I've always thought that XML::LibXML should have a function to strip
> redundant xmlns declarations from a tree.
>
> I've tried...
>
> sub remove_redundant_namespace {
> my $node = shift;
> my $parent = $node->parentNode;
> for my $ns ( $node->getNamespaces ) {
> no warnings 'uninitialized';
> if ($ns->name eq $parent->lookupNamespacePrefix($ns->value)) {
> $node->removeChild($ns);
> }
> }
> remove_redundant_namespace($_) for $node->childNodes;
> }
>
> ...but this doesn't seem to work because
> XML::LibXML::Node::removeChild() does not seem to recognise the
> XML::LibXML::Namespace object as a child.edward.kawas@gmail.com Guest



Reply With Quote

