xpath query root element with the namespace - node.js

I'm trying to address the root element with the namespace and providing a reference to the library xml-crypto.
I'm not giving the path correctly, please advise. Objective is to sign the document so the signature can be inserted right after the tag <samlp:Response
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol" ID="efedb3b0-909f-4b39-b8c0-57427ee8dc83" Version="2.0" IssueInstant="2019-11-08T15:34:51.272Z">
<saml:Issuer xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion">http://www.example.com</saml:Issuer>
</samlp:Response>
nodeJS code
var SignedXml = require('xml-crypto').SignedXml, fs = require('fs');
var sig = new SignedXml();
sig.addReference("//*[local-name(.)='samlp:Response']");
sig.signingKey = fs.readFileSync(__dirname + "/client.pem");
sig.computeSignature(xml);
fs.writeFileSync(__dirname + "/signed.xml", sig.getSignedXml());
Attempts
sig.addReference("//samlp:Response");
Error: Cannot resolve QName samlp
it worked fine at https://www.freeformatter.com/xpath-tester.html though

If you wish to defeat/bypass namespaces, then change
sig.addReference("//*[local-name(.)='samlp:Response']");
to
sig.addReference("//*[local-name()='Response']");
because the namespace prefix, samlp, is not part of the local name, Response.
For a comprehensive answer on namespaces in XPath, see How does XPath deal with XML namespaces?

Related

append a value to existing url in reactjs

I have the following url and a parameter :
number:200
"http://localhost:8000/textpath"
I want the path to be like this:
"http://localhost:8000/textpath/200"
How do I do that using Reactjs?I want to use the appended url in fetch method as follows:
fetch("http://localhost:8000/textpath/200")
A simple append did the work.Doesn't have to complicate
fetch("http://localhost:8000/textpath/"+number)
Try using Template literals.
const url = `http://localhost:8000/textpath/${number}`
fetch(url);
where number = 200
Refer here for more information

Error parsing xml when namespace directives are present

I need to read multiple XML-files using node.js. When the root node contains namespace directives, parsing the xml file fails. When removing the namespace directives, all works well. All my files can have different declarations. How do I parse the XML, ignoring the namespace attributes? I need to use xPath to get some values.
I'm using ...
var fs = require('fs');
var xpath = require('xpath');
var dom = require('xmldom').DOMParser;
var xml = fs.readFileSync('/test.xml', 'utf8').toString();
var doc = new dom().parseFromString(xml);
var id = xpath.select("/export/asset/id", doc);
console.log(id[0].firstChild.data);
XML-file
<export xmlns="some url" xmlns:xsi="some url" format="archive" version="2.4" xsi:schemaLocation="some url.xsd">
<asset>
<id>1445254514291</id>
<name>test</name>
<displayName />
<origin>demo</origin>
</asset>
<export>
Generally speaking, taking into account namespaces is preferable, but if you have to deal with too many of these, one way to avoid them altogether is to use xpath and the somewhat convoluted, but effective, local-name() function.
So I would change
var id = xpath.select("/export/asset/id", doc);
to
var id = xpath.select("//*[local-name()='export']//*[local-name()='asset']//*[local-name()='id']", doc);
With the sample xml in the question, this should output:
"1445254514291"

NodeJS xml2js - removes CDATA tag while converting from XML to JSON

In NodeJS by using xml2js module I am converting the XML string to JSON object and after some edit again converting that JSON object back into XML. All this is working well however the problem is that CDATA tags are missing in the converted XML. Can someone help me with this? I am giving the sample code below which has the same issue.
var xml2js = require('xml2js');
var parser = new xml2js.Parser();
parser.parseString("<myxml myattribute='value'><![CDATA[Hello again]]>
</myxml>", function (err, data) {
var builder = new xml2js.Builder({
cdata: true
});
var xml = builder.buildObject(data);
console.log(" ------------ "+xml);
});
Thanks
-kt
Please read https://github.com/Leonidas-from-XIV/node-xml2js/issues/218
Per the package author, per wikipedia:
A CDATA section is merely an alternative syntax for expressing
character data; there is no semantic difference between character data
that manifests as a CDATA section and character data that manifests as
in the usual syntax in which "<" and "&" would be represented by "<"
and "&", respectively.
The documentation states for the option cdata:
cdata (default: false): wrap text nodes in instead
of escaping when necessary. Does not add if it is
not required. Added in 0.4.5.

Updating a WsdlRequest value via SoapUI Pro

I want to update a WsdlRequest parameter values at runtime using groovy.
Say I have a WsdlRequest that contains two parameters: name, address. I’d like to pass to this WsdlRequest the values I would like the request to have prior to creating a WsdlSubmit instance. I know the base code is this:
WsdlProject project = new WsdlProject()
WsdlInterface iface = WsdlInterfaceFactory.importWsdl(project, wsdl, true)[0]
WsdlOperation operation = (WsdlOperation) iface.getOperationAt(3)
WsdlRequest request = operation.addNewRequest(requestName)
request.setRequestContent (requestContent);
The requestContent is the soapxml in a String format. Is there a good way to insert my values (say I want name value to be ‘Test’ and address value to be ‘Example’ for the request)? I’d rather not store the xml as a string and update this if I already have that information when I generate the request.
Here is an example of the xml:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:data="http://test.com">
<soapenv:Header/>
<soapenv:Body>
<data:updateFieldName>
<fieldId>?</fieldId>
<!--Optional:-->
<newFieldId>?</newFieldId>
</data:updateFieldName>
</soapenv:Body>
</soapenv:Envelope>
Prior to creating the WsdlRequest, I have created a groovy object that contains the values I want to fill into the above soap xml message. Let's say this object states the fieldId = 10 and the newFieldRequest = 15. I a not sure how to pass those values into the request. Is there a way to do this with the SoapUI API? I do have a pro license also.
You can use an XMLHolder to parse your xml, and the you can use setNodeValue(xpath, value) to specify the value for this node, in your case this looks like:
import com.eviware.soapui.support.XmlHolder
// your request content
def requestContent = '<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:data="http://test.com">'+
'<soapenv:Header/>'+
'<soapenv:Body>'+
'<data:updateFieldName>'+
'<fieldId>?</fieldId>'+
'<newFieldId>?</newFieldId>'+
'</data:updateFieldName>'+
'</soapenv:Body>'+
'</soapenv:Envelope>'
// parse it as xml bean
def requestXml = new XmlHolder(requestContent)
// set your node values
requestXml.setNodeValue("//*:fieldId","10");
requestXml.setNodeValue("//*:newFieldId","15");
Then to get the xml content as string again you can use getXml() method as follows:
WsdlRequest request = ...
// to set in your request use getXml()
request.setRequestContent (requestXml.getXml());
For more info you can take a look at XMLHolder api documentation
There is also another way to do this without groovy script; using properties. You can add a properties in for example your TestCase and then use it directly in your TestStep request like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:data="http://test.com">
<soapenv:Header/>
<soapenv:Body>
<data:updateFieldName>
<fieldId>${#TestCase#yourProperty}</fieldId>
<newFieldId>${#TestCase#anotherProperty}</newFieldId>
</data:updateFieldName>
</soapenv:Body>
</soapenv:Envelope>
If you're interested in this take a look at: Working with properties and property expansion
EDIT BASED ON COMMENT:
I write a whole example with your code and xml holder using a public wsdl due you can try and get the result without the NPE and compare with yours to check what is going on:
import com.eviware.soapui.impl.wsdl.WsdlProject
import com.eviware.soapui.impl.wsdl.WsdlInterface
import com.eviware.soapui.impl.WsdlInterfaceFactory
import com.eviware.soapui.impl.wsdl.WsdlOperation
import com.eviware.soapui.impl.wsdl.WsdlRequest
import com.eviware.soapui.support.XmlHolder
wsdl = "http://www.webservicex.net/geoipservice.asmx?WSDL"
WsdlProject project = new WsdlProject()
WsdlInterface iface = WsdlInterfaceFactory.importWsdl(project, wsdl, true )[0]
WsdlOperation operation = (WsdlOperation) iface.getOperationByName( "GetGeoIP" )
WsdlRequest request = operation.addNewRequest("Request")
def defaultRequest = operation.createRequest(true)
def xmlHolder = new XmlHolder(defaultRequest)
xmlHolder.setNodeValue("//*:IPAddress","127.0.0.1");
request.setRequestContent (xmlHolder.getXml());
Hope this helps,
Below is the groovy script for the following:
Update all WSDL Definitions in the project.
Recreate all requests to updated ones.
Takes backup of old requests.
import static com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction.recreateRequests
import static com.eviware.soapui.impl.wsdl.actions.iface.UpdateInterfaceAction.recreateTestRequests
project = testRunner.testCase.testSuite.project; //get the project reference
def ifaceList = project.getInterfaceList(); //get all the interfaces present in the project in a list
//start a loop for number of interfaces
for(int i = 0; i < project.getInterfaceCount() ; i++)
{
def iface = project.getInterfaceAt(i);
def url = iface.definition;
iface.updateDefinition( url, true); //updateDefinition(String url , Boolean createRequests)
//The above part updates the definition
//The part below recreates the requests based on updated wsdl definition
//syntax -
//recreateRequests( WsdlInterface iface, boolean buildOptional, boolean createBackups, boolean keepExisting, boolean keepHeaders )
recreateRequests(iface,true,true,true,true);
recreateTestRequests(iface,true,true,true,true);
}
//End of Script//

Check URL exists in ApplicationContentUriRules

I have an app that is loading URLs into a WebView (x-ms-webview). When the user makes the request, I would like to compare the URL they are trying to load with the "whitelisted" URLs in the ApplicationContentUriRules and warn them if it is not there. Any ideas how I might accomplish this?
There isn't a direct API for pulling information out of the manifest, but there are options.
First, you can just maintain an array of those same URIs in your code, because to change them you'd have to change the manifest and update your package anyway, so you would update the array to match. This would make it easy to check, but increase code maintenance.
Such an array would also let you create a UI in which the user can enter only URIs that will work, e.g. you can offer possibilities from a drop-down list instead of letting the user enter anything.
Second, you can read the manifest XML into a document directly and parse through it to get to the rules. Here's some code that will do that:
var uri = new Windows.Foundation.Uri("ms-appx:///appxmanifest.xml");
var doc;
Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(function (file) {
return Windows.Storage.FileIO.readTextAsync(file);
}).done(function (text) {
doc = new Windows.Data.Xml.Dom.XmlDocument();
doc.loadXml(text);
var acur = doc.getElementsByTagName("ApplicationContentUriRules");
if (acur !== null) {
var rules = acur[0].getElementsByTagName("Rule");
for (var i = 0; i < rules.length; i++) {
console.log(rules[i].getAttribute("Match") + " - " + rules[i].getAttribute("Type"));
}
}
});
You could probably just get "Rule" tags directly from the root doc, because I don't think anything else in the manifest uses that kind of node, but to future-proof it's better to get the ApplicationContentUriRules first. As you can see, the "Match" attribute is what holds the URI for that rule, but you also need to make sure that "Type" is "include" and not "exclude".

Resources