Search code examples
xmlxpathxqueryxpath-2.0xmllint

Need XPath to extract and rearrange data


I am trying to extract the data from xml document but I am failing to do it correctly. Below is the sample xml data from which I need specific string details .

XML file

<BESAPI xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BESAPI.xsd">
    <Action Resource="https://12.13.14.15:52311/api/action/38954" LastModified="Thu, 05 Apr 2018 19:28:54 +0000">
        <Name>*****HOSTING_Dump_SQL_Product_Keys*****</Name>
        <ID>38954</ID>
    </Action>
    <Action Resource="https://12.13.14.15:52311/api/action/40872" LastModified="Thu, 22 Jun 2023 18:42:33 +0000">
        <Name>POLICY - Run Capacity Scan and Upload Results - NoEND</Name>
        <ID>40872</ID>
    </Action>
<Action Resource="https://12.13.14.15:52311/api/action/40872" LastModified="Thu, 22 Jun 2023 18:42:33 +0000">
        <Name>PROD-TEST</Name>
        <ID>40872</ID>
    </Action>
<Action Resource="https://12.13.14.15:52311/api/action/40873" LastModified="Thu, 22 Jun 2023 18:42:33 +0000">
        <Name>PROD-TEST</Name>
        <ID>40873</ID>
    </Action>
</BESAPI>

Now when I run from my MAC terminal the below command , it gives me the Name tag only but I want associated Resource="https:///...." value as well. Please help me formulate xpath query for the same.

xmllint --xpath "/BESAPI/Action/Name/text()" actions.xml | grep -i prod      
PROD-TEST
PROD-TEST

Desired Output

PROD-TEST - https://12.13.14.15:52311/api/action/40872
PROD-TEST - https://12.13.14.15:52311/api/action/40873

Also how to extract both Name and ID part in one XML query. Something like below output

PROD-TEST - 40872
PROD-TEST - 40873

Solution

  • If you use a tool supporting current XPath 3.1/XQuery 3.1 you can use an expression like

    /BESAPI/Action[Name = 'PROD-TEST']/(Name || ' - ' || ID)
    

    There are lots of options to have XPath 3.1 support, if you have Node installed you could install the xslt3 tool with npm and then use e.g. xslt3 -s:actions.xml -xp:"/BESAPI/Action[Name = 'PROD-TEST']/(Name || ' - ' || ID)".