Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6332775
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 24, 20262026-05-24T18:20:56+00:00 2026-05-24T18:20:56+00:00

Having looked at various popular modules for working with XML / XPath I have

  • 0

Having looked at various popular modules for working with XML / XPath I have yet to see a straight-forward way to achieve this.

Essentially the interface would look something like:

my $xpath = get_path($node1, $node2);

…which would return the relative path from $node1 to $node2.

I include my own time in the calculation of ‘efficiency’ – I’ll take any existing solution for this problem. Failing that, I’d like to know some of the pitfalls one might come up against in any ‘obvious’ home-grown solutions.

Off the top of my head I could imagine simply first searching for $node2 in $node1’s descendants, then failing that iterate up $node1’s ancestors doing the same thing. Would that be as raucously resource-intensive as I fear?

For my particular use-case, I can assume the absolute paths of both $node1 and $node2 are known. Given that, I would like to think there’s some ‘XPath math’ that could be done between the two full paths without having to run about all over the tree, but I don’t know what that process would look like.

To summarise:

1) Do any existing CPAN modules make what I want to do easy?

2) If not, what’s an efficient way to go about it?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-24T18:20:56+00:00Added an answer on May 24, 2026 at 6:20 pm

    Find the absolute path for both nodes.

    ref:    root foo bar[2] baz[1] moo
    target: root foo bar[2] baz[2] moo
    

    Remove common leading segments.

    ref:    baz[1] moo
    target: baz[2] moo
    

    For each segment in the reference, prepend the target with a .. segment.

    .. .. baz[2] moo
    

    Convert to XPath.

    ../../baz[2]/moo
    

    Code:

    use XML::LibXML qw( XML_ATTRIBUTE_NODE XML_ELEMENT_NODE );
    
    sub get_path_segs {
       my ($node) = @_;
       my @path = split(/\//, $node->nodePath());
       shift(@path);
       return @path;
    }
    
    sub get_path {
       my ($ref, $targ) = @_;
    
       die if $ref->nodeType()  != XML_ELEMENT_NODE && $ref->nodeType()  != XML_ATTRIBUTE_NODE;
       die if $targ->nodeType() != XML_ELEMENT_NODE && $targ->nodeType() != XML_ATTRIBUTE_NODE;
    
       my @ref  = get_path_segs($ref);
       my @targ = get_path_segs($targ);
    
       while (@ref && @targ && $ref[0] eq $targ[0]) {
          shift(@ref);
          shift(@targ);
       }
    
       while (@ref) {
          pop(@ref);
          unshift(@targ, '..');
       }
    
       return @targ ? join('/', @targ) : '.';
    }
    

    It currently supports element and attribute nodes. It could be expanded to support other node types, possibly trivially.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am looking at creating a configurable product that has various prices. Having looked
I really can't seem to grok RequireJS for some reason (having looked at various
I have been trying to create a hud in my OpenGL application. Having looked
I have used this previously in my app, and having looked over everything I
Having looked at this question, I have the following code: $/ = \0 answer
After having looked at each of these two projects, it seems that both are
I've looked at binary reading and writing objects in c++ but are having some
I've already looked around but couldn't find the exact solution/problem I'm having right now.
OK, so having just got the key to be accepted and have an encrypted
I'm looking for the best method to parse various XML documents using a Java

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.