We are using an AssignMessage policy to set the request to a SOAP target and want to hide the MerchantKey value (which are in the body)
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<SchemaName
xmlns="http://schemas.company.com/company/v46/">
<Credentials>
<MerchantName>Our-Name</MerchantName>
<MerchantKey>{private.key}</MerchantKey>
</Credentials>
<Request>
<RequestBody>123456</RequestBody>
</Request>
</SchemaName>
</soap:Body>
</soap:Envelope>
I have sent in a Data Masking request something like this:
<MaskDataConfiguration name="default">
<Namespaces>
<Namespace prefix="soap">http://schemas.xmlsoap.org/soap/envelope/</Namespace>
<Namespace prefix="FindBoardedCard">http://schemas.merchantwarehouse.com/merchantware/v46/</Namespace>
</Namespaces>
<XPathsRequest>
<XPathRequest>/soap:Envelope/soap:Body/FindBoardedCard/Credentials/MerchantKey</XPathRequest>
</XPathsRequest>
</MaskDataConfiguration>
I have also tried several other permutations. Ideally, I would like to just mask only the MerchantKey. I have attempted to use some xpath evaluators, but for some of these attempts, even though the xpath evaluator would find the element, when enabling the data masking for the same payload and xpath, it wouldn't mask the element. I wasn't able to find any examples which are quite similar to the structure of this payload. Any assistance would be greatly appreciated.
Solved! Go to Solution.
I think I can help you.
XML is complicated, and XML Namespaces make things even more challenging.
Your inbound message
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<SchemaName
xmlns="http://schemas.company.com/company/v46/">
<Credentials>
<MerchantName>Our-Name</MerchantName>
<MerchantKey>{private.key}</MerchantKey>
</Credentials>
<Request>
<RequestBody>123456</RequestBody>
</Request>
</SchemaName>
</soap:Body>
</soap:Envelope>
...uses two distinct namespaces:
The first one uses an explicit namespace prefix: "soap". The way prefixes work: For any element in the document that bears that prefix, the element is said to be defined in the referred namespace (http://www.w3.org...
). The prefix itself carries no meaning. It's just a moniker, a reference to an actual namespace. The following document uses ns1 as the prefix, and is informationally equivalent to yours:
<ns1:Envelope
xmlns:ns1="http://www.w3.org/2003/05/soap-envelope">
<ns1:Body>
<SchemaName
xmlns="http://schemas.company.com/company/v46/">
<Credentials>
<MerchantName>Our-Name</MerchantName>
<MerchantKey>{private.key}</MerchantKey>
</Credentials>
<Request>
<RequestBody>123456</RequestBody>
</Request>
</SchemaName>
</ns1:Body>
</ns1:Envelope>
(Informationally equivalent means, all compliant XML processors should treat it as EXACTLY the same information. to repeat: the actual prefix does not matter, it's the namespace that's important).
The second namespace in your document does not use an explicit namespace prefix. (This is where it gets a little more complicated). When there's no prefix, then, every unqualified element (no prefix and no xmlns= attribute) beneath that parent element is said to be defined in the given namespace. This namespace is known as "the default namespace" for all descendants.
Because of the use of xmlns= with no prefix, elements like SchemaName, Credentials, MerchantName and so on are all defined in the default namespace , which is "http://schemas.company.com/company/v46/"
Using a default namespace is just an alternative to using a prefix. Your document is informationally equivalent to this:
<Envelope
xmlns="http://www.w3.org/2003/05/soap-envelope">
<Body>
<SchemaName
xmlns="http://schemas.company.com/company/v46/">
<Credentials>
<MerchantName>Our-Name</MerchantName>
<MerchantKey>{private.key}</MerchantKey>
</Credentials>
<Request>
<RequestBody>123456</RequestBody>
</Request>
</SchemaName>
</Body>
</Envelope>
and also this:
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<ns1:SchemaName
xmlns:ns1="http://schemas.company.com/company/v46/">
<ns1:Credentials>
<ns1:MerchantName>Our-Name</ns1:MerchantName>
<ns1:MerchantKey>{private.key}</ns1:MerchantKey>
</ns1:Credentials>
<ns1:Request>
<ns1:RequestBody>123456</ns1:RequestBody>
</ns1:Request>
</ns1:SchemaName>
</soap:Body>
</soap:Envelope>
And, for the final twist of complication: there is no analogous "default namespace" mechanism in xpath. If you want to refer to a namespace-qualified element in an XPath expression, you must declare that namespace and its prefix explicitly.
What you want is something like this:
<MaskDataConfiguration name="default">
<Namespaces>
<Namespace prefix="s">http://www.w3.org/2003/05/soap-envelope</Namespace>
<Namespace prefix="ns1">http://schemas.company.com/company/v46/</Namespace>
</Namespaces>
<XPathsRequest>
<XPathRequest>/s:Envelope/s:Body/ns1:SchemaName/ns1:Credentials/ns1:MerchantKey</XPathRequest>
</XPathsRequest>
</MaskDataConfiguration>
Things to notice:
http://schemas.xmlsoap.org/etc
, and the document you provided uses http://www.w3.org/etc
. They do not match. The former is the soap 1.1 namespace, the latter is used with soap 1.2. (more on that)I think I can help you.
XML is complicated, and XML Namespaces make things even more challenging.
Your inbound message
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<SchemaName
xmlns="http://schemas.company.com/company/v46/">
<Credentials>
<MerchantName>Our-Name</MerchantName>
<MerchantKey>{private.key}</MerchantKey>
</Credentials>
<Request>
<RequestBody>123456</RequestBody>
</Request>
</SchemaName>
</soap:Body>
</soap:Envelope>
...uses two distinct namespaces:
The first one uses an explicit namespace prefix: "soap". The way prefixes work: For any element in the document that bears that prefix, the element is said to be defined in the referred namespace (http://www.w3.org...
). The prefix itself carries no meaning. It's just a moniker, a reference to an actual namespace. The following document uses ns1 as the prefix, and is informationally equivalent to yours:
<ns1:Envelope
xmlns:ns1="http://www.w3.org/2003/05/soap-envelope">
<ns1:Body>
<SchemaName
xmlns="http://schemas.company.com/company/v46/">
<Credentials>
<MerchantName>Our-Name</MerchantName>
<MerchantKey>{private.key}</MerchantKey>
</Credentials>
<Request>
<RequestBody>123456</RequestBody>
</Request>
</SchemaName>
</ns1:Body>
</ns1:Envelope>
(Informationally equivalent means, all compliant XML processors should treat it as EXACTLY the same information. to repeat: the actual prefix does not matter, it's the namespace that's important).
The second namespace in your document does not use an explicit namespace prefix. (This is where it gets a little more complicated). When there's no prefix, then, every unqualified element (no prefix and no xmlns= attribute) beneath that parent element is said to be defined in the given namespace. This namespace is known as "the default namespace" for all descendants.
Because of the use of xmlns= with no prefix, elements like SchemaName, Credentials, MerchantName and so on are all defined in the default namespace , which is "http://schemas.company.com/company/v46/"
Using a default namespace is just an alternative to using a prefix. Your document is informationally equivalent to this:
<Envelope
xmlns="http://www.w3.org/2003/05/soap-envelope">
<Body>
<SchemaName
xmlns="http://schemas.company.com/company/v46/">
<Credentials>
<MerchantName>Our-Name</MerchantName>
<MerchantKey>{private.key}</MerchantKey>
</Credentials>
<Request>
<RequestBody>123456</RequestBody>
</Request>
</SchemaName>
</Body>
</Envelope>
and also this:
<soap:Envelope
xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<ns1:SchemaName
xmlns:ns1="http://schemas.company.com/company/v46/">
<ns1:Credentials>
<ns1:MerchantName>Our-Name</ns1:MerchantName>
<ns1:MerchantKey>{private.key}</ns1:MerchantKey>
</ns1:Credentials>
<ns1:Request>
<ns1:RequestBody>123456</ns1:RequestBody>
</ns1:Request>
</ns1:SchemaName>
</soap:Body>
</soap:Envelope>
And, for the final twist of complication: there is no analogous "default namespace" mechanism in xpath. If you want to refer to a namespace-qualified element in an XPath expression, you must declare that namespace and its prefix explicitly.
What you want is something like this:
<MaskDataConfiguration name="default">
<Namespaces>
<Namespace prefix="s">http://www.w3.org/2003/05/soap-envelope</Namespace>
<Namespace prefix="ns1">http://schemas.company.com/company/v46/</Namespace>
</Namespaces>
<XPathsRequest>
<XPathRequest>/s:Envelope/s:Body/ns1:SchemaName/ns1:Credentials/ns1:MerchantKey</XPathRequest>
</XPathsRequest>
</MaskDataConfiguration>
Things to notice:
http://schemas.xmlsoap.org/etc
, and the document you provided uses http://www.w3.org/etc
. They do not match. The former is the soap 1.1 namespace, the latter is used with soap 1.2. (more on that)@dchiesa1 Works great now. Thanks so much! The non-explicit namespaces--and namespaces in general--tend to throw me.