Send UTF-16 encoded SOAP request with Ruby and Savon - ruby

How do I encode the request in UTF-16? Here's what I have:
# Create Savon client
#client = Savon::Client.new do
wsdl.document = File.expand_path("account_list.wsdl", __FILE__)
end
# Set header encoding
#client.http.headers["Content-Type"] = "text/xml;charset=UTF-16"
# Setup ssl configuration
#client.http.auth.ssl.cert_key_file = "cert_key_file.pem"
#client.http.auth.ssl.cert_file = "cert_file.pem"
#client.http.auth.ssl.ca_cert_file = "ca_cert_file.pem"
#client.http.auth.ssl.verify_mode=:none
# Execute request
response = #client.request :account_list do
soap.body = {
:id => "18615618"
}
end
Here's the begging of what's sent, notice the encoding="UTF-8":
Content-Type: text/xml;charset=UTF-16, SOAPAction: "accountList", Content-Length: 888 <?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema
Here's the error I get:
< s o a p : E n v e l o p e x m l n s : s o a p = " h t t p : / / s c h e m a s . x m l s o a p . o r g / s o a p / e n v e l o p e / " x m l n s : w s>d
< s o a p : B o d y >
< s o a p : F a u l t >
< f a u l t c o d e > s o a p : C l i e n t < / f a u l t c o d e >
< f a u l t s t r i n g > F a i l e d t o p r o c e s s S O A P r e q u e s t . S O A P b o d y n o t i n U T F - 1 6 .
< / f a u l t s t r i n g >
< d e t a i l >
< w s d l _ o p s : e r r o r > F a i l e d t o p r o c e s s S O A P r e q u e s t . S O A P b o d y n o t i n U T F - 1 6 .
< / w s d l _ o p s : e r r o r >
< / d e t a i l >
< / s o a p : F a u l t >
< / s o a p : B o d y >
< / s o a p : E n v e l o p e >

Savon currently only supports changing the XML directive tag via the integrated Builder-method:
response = #client.request(:account_list) do
soap.xml(:xml, :encoding => "UTF-16") { |xml| xml.id("18615618") }
end
You'll miss out a lot of XML-support by using this approach though. No SOAP envelope, no header or body:
<?xml version="1.0" encoding="UTF-16"?><id>18615618</id>
I'll use your ticket to come up with a better solution asap!

Related

Freemarker trimming right spaces not working

I will be as simple as possible , i have the below template.ftl
B E G L E I T Z E T T E L Intern
FUER DATEI: ${content.fileName}
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
ERZ. SYSTEM: ${content.system}
INITIATOR: ${content.initiator}
DATEI ID: ${content.fileID}
And i want to output :
B E G L E I T Z E T T E L Intern
FUER DATEI: FileName
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
ERZ. SYSTEM: SYSTEMX
INITIATOR: Initiator
DATEI ID: FileID
But what i get instead ... let's say for the above example is :
B E G L E I T Z E T T E L Intern
FUER DATEI: FileName
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
ERZ. SYSTEM: SYSTEMX
INITIATOR: Initiator
DATEI ID: FileID
In other words the column is not properly aligned
How can i fix this problem in FreeMarker :) ?
Add <#rt> for trimming right spaces
B E G L E I T Z E T T E L Intern
FUER DATEI: ${content.fileName}<#rt>
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
ERZ. SYSTEM: ${content.system}<#rt>
INITIATOR: ${content.initiator}<#rt>
DATEI ID: ${content.fileID}<#rt>
rt (for right trim): Ignore all trailing white-space in this line.
Notice to add new lines between lines, for example:
B E G L E I T Z E T T E L Intern
FUER DATEI: ${content.fileName}<#rt>
--------------------------------------------------------------------------------
Here is the answer , i used something not very complex:
<#assign lineWidth = 80>
B E G L E I T Z E T T E L Intern
<#compress>FUER DATEI: </#compress>${content.fileName?left_pad(lineWidth-"FUER DATEI:"?length," ")}
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
<#compress>ERZ. SYSTEM: </#compress>${content.system?left_pad(lineWidth-"ERZ. SYSTEM:"?length," ")}
<#compress>INITIATOR: </#compress>${content.initiator?left_pad(lineWidth-"INITIATOR:"?length," ")}
<#compress>DATEI ID: </#compress>${content.fileID?left_pad(lineWidth-"DATEI ID:"?length," ")}
So let's take the 3 first lines of code :
<#assign lineWidth = 80>
B E G L E I T Z E T T E L Intern
<#compress>FUER DATEI: </#compress>${content.fileName?left_pad(lineWidth-"FUER DATEI:"?length," ")}
1. Firstly i assign a variable lineWidth which represents the maximum line width of the file.
2. Then for each line i eat all the spaces using <#compress>
3. Then i added the value and left added the needed spaces in a way that everything aligns right.
----- BOSS LEVEL BELOW - using functions -----
<#assign lineWidth = 80>
<#function createLine prefix value >
<#return prefix + value?left_pad(lineWidth - prefix?length," ")>
</#function>
B E G L E I T Z E T T E L Intern
${createLine("FUER DATEI:",content.fileName)}
--------------------------------------------------------------------------------
BELEGLOSER DATENTRAEGERAUSTAUSCH
${createLine("ERZ. SYSTEM:",content.system)}
${createLine("INITIATOR:",content.initiator)}
${createLine("DATEI ID:",content.fileID)}
${createLine("SAMMELREFERENZ ID:",content.referenceID)}
${createLine("RSTELLUNGSDATUM:",content.creationDate)}

How to sort a list of full names by how common the ancestors are?

If every letter in the following represents a name. What is the best way to sort them by how common the ancestors are?
A B C D
E F G H
I J K L
M N C D
O P C D
Q R C D
S T G H
U V G H
W J K L
X J K L
The result should be:
I J K L # Three names is more important that two names
W J K L
X J K L
A B C D # C D is repeated more than G H
M N C D
O P C D
Q R C D
E F G H
S T G H
U V G H
EDIT:
Names might have spaces in them (Double names).
Consider the following example where each letter represents a single word:
A B C D M
E F G H M
I J K L M
M N C D M
O P C D
Q R C D
S T G H
U V G H
W J K L
X J K L
The output should be:
A B C D M
M N C D M
I J K L M
E F G H M
W J K L
X J K L
O P C D
Q R C D
S T G H
U V G H
First count the number of occurrences for each chain. Then rank each name according to that count. Try this:
from collections import defaultdict
words = """A B C D
E F G H
I J K L
M N C D
O P C D
Q R C D
S T G H
U V G H
W J K L
X J K L"""
words = words.split('\n')
# Count ancestors
counters = defaultdict(lambda: defaultdict(lambda: 0))
for word in words:
parts = word.split()
while parts:
counters[len(parts)][tuple(parts)] += 1
parts.pop(0)
# Calculate tuple of ranks, used for sorting
ranks = {}
for word in words:
rank = []
parts = word.split()
while parts:
rank.append(counters[len(parts)][tuple(parts)])
parts.pop(0)
ranks[word] = tuple(rank)
# Sort by ancestor count, longest chain comes first
words.sort(key=lambda word: ranks[word], reverse=True)
print(words)
Here's how you could do it in Java - essentially the same method as #fafl's solution:
static List<Name> sortNames(String[] input)
{
List<Name> names = new ArrayList<>();
for (String name : input)
names.add(new Name(name));
Map<String, Integer> partCount = new HashMap<>();
for (Name name : names)
for (String part : name.parts)
partCount.merge(part, 1, Integer::sum);
for (Name name : names)
for (String part : name.parts)
name.counts.add(partCount.get(part));
Collections.sort(names, new Comparator<Name>()
{
public int compare(Name n1, Name n2)
{
for (int c, i = 0; i < n1.parts.size(); i++)
if ((c = Integer.compare(n2.counts.get(i), n1.counts.get(i))) != 0)
return c;
return 0;
}
});
return names;
}
static class Name
{
List<String> parts = new ArrayList<>();
List<Integer> counts = new ArrayList<>();
Name(String name)
{
List<String> s = Arrays.asList(name.split("\\s+"));
for (int i = 0; i < s.size(); i++)
parts.add(String.join(" ", s.subList(i, s.size())));
}
}
Test:
public static void main(String[] args)
{
String[] input = {
"A B C D",
"W J K L",
"E F G H",
"I J K L",
"M N C D",
"O P C D",
"Q R C D",
"S T G H",
"U V G H",
"X J K L" };
for (Name name : sortNames(input))
System.out.println(name.parts.get(0));
}
Output:
I J K L
W J K L
X J K L
A B C D
M N C D
O P C D
Q R C D
E F G H
S T G H
U V G H

How to create a analysis table for a logic propositions

I have this is grammar:
F = F and F
F = F or F
F = F => F
F = F <=> F
F = not F
F = (F)
D = a
but this grammar has an ambiguity, I have stripped the ambiguity like this:
F = F and A
F = A
A = F or B
A = B
B = F => C
B = C
C = F <=> C
C = D
D = not F
D = (F)
D = a
its true or no ?

How to custom the display order of polynomial in Mathematica

For example, I have
A = a*c*b + d*c*b + d*c*t
Where b and t are more like variables and a,c,d are more like parameters.
It would be displayed as
a b c + b c d + c d t
what I want is let it be displayed as
a c b + d c b + d c t
Where b and t are in the end.
Dirty trick:
a*c*b + d*c*b + d*c*t /. Thread[# -> (Interpretation[ToString[#], #] & /# #)] &#{b, t}
a c b + c d b + c d t

Simple equations solving

Think of a equations system like the following:
a* = b + f + g
b* = a + c + f + g + h
c* = b + d + g + h + i
d* = c + e + h + i + j
e* = d + i + j
f* = a + b + g + k + l
g* = a + b + c + f + h + k + l + m
h* = b + c + d + g + i + l + m + n
...
a, b, c, ... element of { 0, 1 }
a*, b*, c*, ... element of { 0, 1, 2, 3, 4, 5, 6, 7, 8 }
+ ... a normal integer addition
Some of the variables a, b, c... a*, b*, c*... are given. I want to calculate as much other variables (a, b, c... but not a*, b*, c*...) as logically possible.
Example:
given: a = 0; b = 0; c = 0;
given: a* = 1; b* = 2; c* = 1;
a* = b + f + g ==> 1 = 0 + f + g ==> 1 = f + g
b* = a + c + f + g + h ==> 2 = 0 + 0 + f + g + h ==> 2 = f + g + h
c* = b + d + g + h + i ==> 1 = 0 + d + g + h + i ==> 1 = d + g + h + i
1 = f + g
2 = f + g + h ==> 2 = 1 + h ==> h = 1
1 = d + g + h + i ==> 1 = d + g + 1 + i ==> d = 0; g = 0; i = 0;
1 = f + g ==> 1 = f + 0 ==> f = 1
other variables calculated: d = 0; f = 1; g = 0; h = 1; i = 0;
Can anybody think of a way to perform this operations automatically?
Brute force may be possible in this example, but later there are about 400 a, b, c... variables and 400 a*, b*, c*... variables.
This sounds a little like constraint propogation. You might find "Solving every Sudoku Puzzle" a good read to get the general idea.
The problem is NP-complete. Look at the system of equations:
2 = a + c + d1
2 = b + c + d2
2 = a + b + c + d3
Assume that d1,d2,d3 are dummy variables that are only used once and hence add no other constraints that di=0 or di=1. Hence from the first equation follows c=1 if a=0. From the second equation follows c=1 if b=0 and from the third one we get c=0 if a=1 and b=1 and hence we get the relation
c = a NAND b.
Thus we can express any boolean circuit using such a system of equations and therefore the boolean satisfyability problem can be reduced to solving such a system of equations.

Resources