namespace declarations in LibXML

Ask a Question related to PERL Modules, Design and Development.

  1. #1

    Default 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

  2. Similar Questions and Discussions

    1. 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...
    2. #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: ...
    3. #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: ...
    4. 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...
    5. [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...
  3. #2

    Default Re: namespace declarations in LibXML

    [email]edward.kawas@gmail.com[/email] wrote:
    > 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?
    Just a WAG, but try something like this on the top element before
    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

  4. #3

    Default Re: namespace declarations in LibXML

    Hi Steve, that didnt help.

    Thanks.

    edward.kawas@gmail.com Guest

  5. #4

    Default Re: namespace declarations in LibXML


    [email]edward.kawas@gmail.com[/email] wrote:
    > 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>
    Why do you care? The two are semantically identical. Are you concened
    about file size or the aesthetic appeal of the XML source?
    > How can i achieve this?
    I've seen similar problems myself. Perhaps if you posted a _minimal_
    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

  6. #5

    Default 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

  7. #6

    Default Re: namespace declarations in LibXML


    [email]edward.kawas@gmail.com[/email] wrote:
    > 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);
    Here you are explicitly re-inroducing the namespace in the child nodes.

    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

  8. #7

    Default 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

  9. #8

    Default Re: namespace declarations in LibXML


    [email]edward.kawas@gmail.com[/email] wrote:
    > <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.
    Opps...

    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

  10. #9

    Default Re: namespace declarations in LibXML

    Is there any way to not hard code the namespace prefix?

    Thanks,

    Eddie

    edward.kawas@gmail.com Guest

  11. #10

    Default Re: namespace declarations in LibXML


    [email]edward.kawas@gmail.com[/email] wrote:

    [ no context given ]
    > Is there any way to not hard code the namespace prefix?
    I'm sorry I do not understand the question.

    Brian McCauley Guest

  12. #11

    Default 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

  13. #12

    Default Re: namespace declarations in LibXML

    sorry,
    $root->addTextElement("blah blah");
    should read:
    $root->appendTextChild("D", "blah");

    edward.kawas@gmail.com Guest

  14. #13

    Default Re: namespace declarations in LibXML

    [email]edward.kawas@gmail.com[/email] wrote:

    [ No relevant context given. Please try to follow accepted conventions.
    ]
    > you hard-coded the prefix, i.e. $c->setAttribute("foo:foo", "name");
    > can we avoid this somehow?
    I did avoid it in the alternative method I showed you about three lines
    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

  15. #14

    Default 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

  16. #15

    Default Re: namespace declarations in LibXML


    [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.

    Brian McCauley Guest

  17. #16

    Default 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

Posting Permissions

  • You may not post new threads
  • You may post replies
  • You may not post attachments
  • You may not edit your posts

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139