问题
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