I just got a doubt whether the XMLs we are using for our SOAP/REST-based web services are case-sensitive or or not? How does it work exactly?
Tell me both for the default soap envelope as well as for payload XMLs.
SOAP is a specific instance of an XML language.
As such, it adheres to all the rules of XML.
One of these rules is that XML is case-sensitive.
Therefore SOAP is case sensitive as well.
Same is true for REST
XML is always case-sensitive; it's defined that way by the W3C (see the definition for “match” where it says that no case folding is performed). SOAP uses XML for both envelope and payload, so those are by definition case-sensitive.
(Note that this is different from HTML, which is case-insensitive for element and attribute names. That's because HTML is built on top of SGML, itself a much-more-complex predecessor to XML.)
Related
I'm writing some tests for my web service right now and can't find a lot of information regarding xPath match and Contains. Looking for examples as well.
1) For example, I would like to check if the date has format YYYY-MM-DD.
Do i have to write regex expression in expected result?
http://prntscr.com/jhlxml
2) How can I check if answer equals to one of allowed values (using xsd enumeration)?
http://prntscr.com/jhm07g
If you have control over the WSDL, those sorts of format and simple content validations can be built into the XML Schema within your WSDL that defines your response messages. Then, just use a Schema Compliance assertion on your test step.
I know I cannot use regular expressions for the <url-pattern> of a filter-mapping, but is it possible to use a directory pattern to specify any url containing the word myuniqws as in:
https://my.hostname.org/myuniqws/myport/soap?wsdl
I am thinking of perhaps this would be the correct syntax:
<url-pattern>/*myuniqws*</url-pattern>
but I have not been able to find documentation for the exact rule of Tomcat's <url-pattern> syntax.
Will the above regex work as I desire?
Update:
Thanks to the answer below, I discovered the following section in the Java Servlet Specification, which basically answers my questions.
12.2 Specification of Mappings
In the Web application deployment descriptor, the following syntax is used to define
mappings:
A string beginning with a ‘/’ character and ending with a ‘/*’ suffix is used for
path mapping.
A string beginning with a ‘*.’ prefix is used as an extension mapping.
The empty string ("") is a special URL pattern that exactly maps to the application's context root, i.e., requests of the form http://host:port/<contextroot>/. In this case the path info is ’/’ and the servlet path and context path is empty string (““).
A string containing only the ’/’ character indicates the "default" servlet of the application. In this case the servlet path is the request URI minus the context path and the path info is null.
All other strings are used for exact matches only.
If the effective web.xml (after merging information from fragments and annotations) contains any url-patterns that are mapped to multiple servlets then the deployment must fail.
Presumably, you mean the <url-pattern> for filter mappings in web.xml. You might not know this, but web.xml is defined as part of the Java Servlet Specification. You can find full documentation for the 3.1 version (currently, the latest and greatest) here:
https://jcp.org/aboutJava/communityprocess/final/jsr340/index.html
If you read section 12.2 ("Specification of Mappings") you can see exactly what kinds of patterns are recognized, including the prefix-mapping you are requesting above.
EDIT 2014-11-04:
You should know that CATALINA_HOME/conf/web.xml (or CATALINA_BASE/conf/web.xml if you have one) is the default configuration for all web applications deployed on Tomcat and that your webapp's WEB-INF/web.xml is the configuration specific for your own web application. Both of these files should have the following xmlns statements and therefore indicate to you (by their URIs) that they are covered by the Java Servlet Specification (or at least Java EE, which includes the servlet spec):
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
I am using camel to implement a proxy over a new backend that looks like an older interface. The older API has username/password credentials in the request body and the new backend service uses basic auth. I have an XSL that will extract the un/pw, do a simple lookup against an XML database (the credentials might not map exactly), and will return the correct credentials as a base64 encoded string. I cannot figure out how to set this as an http Authentication header value (e.g. how to process an XSL transform as an expression in .setHeader() call).
I have SOAP requests that look like this:
<soapenv:Envelope>
<soapenv:Body>
<XService>
<_Header username="demo" password="demo"/>
<_Body>
<_RequestParameters xsi:type="RequestServiceReport">
...
</_RequestParameters>
</_Body>
</XService>
</soapenv:Body>
and my route (using Java DSL) looks sort of like this:
from("jetty:http://161.228.88.168:8080/sap2rjm")
.choice()
.when().simple("${header.channel}")
...
.when().simple("${in.header.emx} == 'authenticate'")
...
.endChoice()
// If the request is for a report, route it to the new service
.when().xpath("//_RequestParameters[#type='RequestServiceReport']")
// TODO: How to get header from the body of the message and set as the header value?
// Stylesheet transform_credentials will extract username/password from body, transform
// for the new service (dev.reportjam) and will base4 encode to produce a string like this one...
.setHeader("Authorization", constant("Basic ZGVtbzpkZW1v"))
.to("xslt:transform_request.xsl")
.to("http://dev.reportjam.com/services/ReportMix?bridgeEndpoint=true")
.to("xslt:transform_response.xsl")
.removeHeaders("*")
.endChoice()
.otherwise()
...
.endChoice()
.end();
I do have another stylesheet that will process the soap request, extract the un/pw, apply some logic to transform it, and then base64 encode it but I do not know how to call this in the setHeader() call above.
Thanks
You can use xpath to grab something from an XML body and then store that as a header.
http://camel.apache.org/xpath
.setHeader("foo", xpath("/foo/bar"))
The trick is to write the xpath expression so it works. As your XML message uses namespaces you need to use them in the xpath expression also. See that link for more details.
Also you should enable stream caching as you will read the message body as part of this xpath expression evaluation.
See the top of this link about stream caching and jetty: http://camel.apache.org/jetty
What does a namespace do in XSLT when a url is provided such as:
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
does this attempt to make a connection to the internet?
No; it just so happens that the specification for XML Namespaces (see W3C XSL Namespace specifications) are URI's.
They work in exactly the same way that namespaces in other languages do; they help uniquely identify things with the same names but in different contexts.
You can prove that no attempt is made to retrieve the resource by using a HTTP Monitor on your machine while loading or using the XSL Transformation - this answer has many good suggestions.
No.
Whatever the namespace is in a xsd, an xslt or any other xml file, there is no internet request.
The namespace is used to qualified your xml element.
When you conduct an XSLT transformation, the XSLT engine validates the XSLT file. It performs many checks, such as the root element being named stylesheet, etc. The engine must also be able to discern literal result elements (like <table>) from XSLT-specific elements (like <xsl:stylesheet>).
An element is recognized as XSLT-specific when it resides in the XSLT namespace. The value of the URI you posted (http://www.w3.org/1999/XSL/Transform) is simply a convention that makes it clear we're talking about XSLT. The prefix being defined (xsl) is the prefix used in the XSLT file to qualify the XSLT elements. You can use another prefix if you choose, provided you map it to the XSLT namespace.
Note that it's actually just a URI (an identifier), not a URL (a locator). There is no HTTP request to locate anything, it just identifies an abstract concept (in this case "XSLT").
XSL requires this at the top of every stylesheet:
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
and throws an error if the url in the namespace is not exactly right.
Today, "http://www.w3.org/1999/XSL/Transform" is offline. I cannot run any transformations. The transformation hangs and then returns "unexpected end of file" when the net request times out. If I change the URL in the namespace declaration to a random URL, the transformation fails with an error telling me that "http://www.w3.org/1999/XSL/Transform" is the required xsl namespace.
So how do I work around W3's site being down?
Using xmlns:something="..." declares an XML namespace. Such a namespace is merely a string, something that will help to attribute a unique meaning to element names like template or href, making sure multiple XML-based languages can be used in a single document without creating confusion as to its meaning.
Some of those namespaces are reserved for use by the W3C. The XSLT namespace is one of those. A proper XSLT processor will check if a stylesheet declares the correct namespace to make sure there can be no incorrect interpretation. The root element of the stylesheet should be in that XSLT namespace.
For an actual namespace value, you'd usually have a URI (and most often a URL) since that's normally a good unique identifier. However, this should never be used to actually resolve to any online resources during XML processing. Whereas HTTP URLs are normally treated in a case-insensitive manner and may make use of URL encoding for characters (e.g. space becomes %20), such resolution or equality of URLs is not checked in XML namespace processing. A namespace in XML is nothing but a string that's always checked in its exact form, casing and everything.
So if an XSLT processor complains that some resource at a URL cannot be found, then either it's doing something it shouldn't do, or the problem has nothing to do with namespace processing.
You're using Saxon, which most definitely isn't a processor that doesn't understand the concept of a namespace. Its father is Michael Kay who is also responsible for the XSLT 2.0 spec. But Saxon does support schema-aware XSLT processing. If a document specifies a schema location, then a processor using this for validation would actually use that location to get the schema. That's the difference with a namespace. DTDs and XML Schema locations can definitely result in network activity.
So I advise you to check if...
the XML uses a DTD with external definitions and whether those are available;
the XML specifies a schema location and whether that location can be reached;
the stylesheet makes use of a schema or some other external resource and whether that's available.
Once you've found the cause, look into the use of XML catalogs in conjunction with the processor. An XML catalog will allow you to use local resources if they can't be resolved from their URIs.
Simple answer: The http://www.w3.org/1999/XSL/Transform isn't a URL, it's just a string. If W3C had decided, there's no reason it couldn't have been 'ThisIsAnXsltStylesheet'. By convention, they usually resemble URL's, but this isn't required.
So, the fact that there's nothing at that URL isn't relevant to why your stylesheet is failing, and certainly won't be the cause. Logically speaking, if that were the case, then nobody without an internet connection would ever be able to use XSLT, and w3c's servers would be seriously overworked.
I'd recommend adding the first few lines of your XSLT into your question; it might shed some light on where your problem really is.