I need to extract (XSLT, xpath, xquery... Preferably xpath) the most deeply nested element nodes with method (DEST id="RUSSIA" method="delete"/>) and his direct ancestor (SOURCE id="AFRICA" method="modify">).
I don't want to get the top nodes with methods ( main method="modify"> or main method="modify"> ).
The deepest nested elements with method correspond to real actions. The top elements with method actually are dummy actions that must not be taken into account.
Here is my XML sample file:
<?xml version="1.0" encoding="UTF-8"?>
<main method="modify">
<MACHINE method="modify">
<SOURCE id="AFRICA" method="modify">
<DEST id="RUSSIA" method="delete"/>
<DEST id="USA" method="modify"/>
</SOURCE>
<SOURCE id="USA" method="modify">
<DEST id="AUSTRALIA" method="modify"/>
<DEST id="CANADA" method="create"/>
</SOURCE>
</MACHINE>
</main>
This is Xpath output I expect:
<SOURCE id="AFRICA" method="modify"><DEST id="RUSSIA" method="delete"/>
<SOURCE id="AFRICA" method="modify"><DEST id="USA" method="modify"/>
<SOURCE id="USA" method="modify"><DEST id="AUSTRALIA" method="modify"/>
<SOURCE id="USA" method="modify"><DEST id="CANADA" method="create"/>
My current xpath command does not provide the adequate result.
Command xpath("//[@method]/ancestor::*") which is returning:
<main><MACHINE method="modify"> # NOT WANTED
<MACHINE method="modify"><SOURCE id="AFRICA" method="modify"> # NOT WANTED
<MACHINE method="modify"><SOURCE id="USA" method="modify"> # NOT WANTED
<SOURCE id="AFRICA" method="modify"><DEST id="RUSSIA" method="delete"/>
<SOURCE id="AFRICA" method="modify"><DEST id="USA" method="modify"/>
<SOURCE id="USA" method="modify"><DEST id="AUSTRALIA" method="modify"/>
<SOURCE id="USA" method="modify"><DEST id="CANADA" method="create"/>
My xmltwig code for additional information (context):
#!/usr/bin/perl -w
use warnings;
use XML::Twig;
use XML::XPath;
@my $t= XML::Twig->new;
my $v= XML::Twig::Elt->new;
$t-> parsefile ('input.xml');
@abc=$t->get_xpath("\/\/[\@method]\/ancestor\:\:\*") ;
foreach $v (@abc) # outer 1
{
foreach $v ($v ->children) # internal 1
{
$w=$v->parent;
print $w->start_tag;
print $v->start_tag;
}
}
SOURCE
element to contain theDEST
elements or if you want to flatten the existing hierarchy and output all elements on the same level. – Chrysler//[@method]/ancestor::*
. Let me know if it possible with xpath to filter the farthest node with method (and to include his direct ancestor). If not possible (then we use XSLT), I will modify the question by having an XML file as OUTPUT – Lylalylecurrent()
function. Otherwise, the solution would be select all elements for which there are no other elements with a greater number of ancestors. Using XSLT, this can be expressed. – Redoubt"//[@method]/ancestor::*"
is not legal XPath and should give you a syntax error. – Darkcurrent()
function"] Two of the answers do provide such expression. – Kleiman