XPath take element on double condition

余生颓废 提交于 2020-07-10 03:11:14

问题


I have an InformationModel from OPC-UA, written in xml (https://github.com/OPCFoundation/UA-Nodeset/blob/v1.04/Robotics/Opc.Ua.Robotics.NodeSet2.xml). From this model I want to: Look at the reference inside an UAObject and get the DisplayName only if the reference has 1)The nodeid I am looking for 2)Has a field IsRecursive="false"

I tried this code for getting all object with a reference which point to my specified nodeid and it works. Here it is the code for it:

var ObjectsName2 = select(
    "//ns1:References/ns1:Reference[.=" +
      formatted_id + "]/ancestor::ns1:UAObject/ns1:DisplayName/text()",
    nodes,
    false
  );

Now I want to take the one that has the specific nodeid and has field IsForward setted to "false". So I have a double condition that needs to be verified with an AND. Here it is the code I am using:

var formatted_id = '"' + ParentNodeId + '"';
  var negate = "false";
  var ObjectsName = select(
    "//ns1:References/ns1:Reference[.=" +
      formatted_id + 
      "//@ns1:IsForward="+negate+"]/ancestor::ns1:UAObject/ns1:DisplayName/text()",
    nodes,
    false
  );

The wrong result is an empty array. To make a bit easier to understand here it is an example that shows what I want.

Imagine you have this xml entry and the node that I am looking for is ns=1;i=15008:

<UAObject NodeId="ns=1;i=15024" BrowseName="2:ParameterSet" ParentNodeId="ns=1;i=15008">
   <DisplayName>ParameterSet</DisplayName>
   <Description>Flat list of Parameters</Description>
   <References>
     <Reference ReferenceType="HasComponent">ns=1;i=15061</Reference>
     <Reference ReferenceType="HasTypeDefinition">i=58</Reference>
     <Reference ReferenceType="HasModellingRule">i=78</Reference>
     <Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=15008</Reference>
   </References>
 </UAObject>

As you can see there is a Reference called "HasComponent" which points to my node (ns=1;i=15008) and IsForward="false".

The expected output should be the display name of the UAObject in the output array -->ParameterSet Can someone help me?


回答1:


Simply based on xpath alone, this expression:

//Reference[@ReferenceType="HasComponent"][@IsForward="false"]

should select ns=1;i=15008 in your sample xml.




回答2:


so you want to find the Reference node that has ReferenceType is HasComponent and IsForward is false, from that, go up 1 level find the DisplayName ?

const {transform} = require('camaro')

;(async function main() {
    const xml = `
    <UAObject NodeId="ns=1;i=15024" BrowseName="2:ParameterSet" ParentNodeId="ns=1;i=15008">
        <DisplayName>ParameterSet</DisplayName>
        <Description>Flat list of Parameters</Description>
        <References>
            <Reference ReferenceType="HasComponent">ns=1;i=15061</Reference>
            <Reference ReferenceType="HasTypeDefinition">i=58</Reference>
            <Reference ReferenceType="HasModellingRule">i=78</Reference>
            <Reference ReferenceType="HasComponent" IsForward="false">ns=1;i=15008</Reference>
        </References>
    </UAObject>
    `
    const template = {
        names: ['//References/Reference[@ReferenceType="HasComponent" and @IsForward="false"]', '../../DisplayName']
    }
    console.log(await transform(xml, template), null, 4);
})()

out

{ names: [ 'ParameterSet' ] }


来源:https://stackoverflow.com/questions/62753920/xpath-take-element-on-double-condition

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!