XQuery to group xml elements - xquery

I was trying some grouping in xquery
<Sheets>
<Sheet>
<ROI>5350</ROI>
<TPI>830</TPI>
</Sheet>
<Sheet>
<ROI>5459</ROI>
<TPI>830</TPI>
</Sheet>
<Sheet>
<ROI>5350</ROI>
<TPI>856</TPI>
</Sheet>
<Sheet>
<ROI>5678</ROI>
<TPI>856</TPI>
</Sheet>
<Sheet>
<ROI>17473</ROI>
<TPI>856</TPI>
</Sheet>
<Sheet>
<ROI>5350</ROI>
<TPI>857</TPI>
</Sheet>
<Sheet>
<ROI>5713</ROI>
<TPI>857</TPI>
</Sheet>
</Sheets>
in my xquery, i want to pass a dynamic value say number 4... i want my xml to group to 4 Sheet elements to one set like
<Sheets>
<set>
<Sheet>
<ROI>5350</ROI>
<TPI>830</TPI>
</Sheet>
<Sheet>
<ROI>5459</ROI>
<TPI>830</TPI>
</Sheet>
<Sheet>
<ROI>5350</ROI>
<TPI>856</TPI>
</Sheet>
<Sheet>
<ROI>5678</ROI>
<TPI>856</TPI>
</Sheet>
</set>
<set>
<Sheet>
<ROI>17473</ROI>
<TPI>856</TPI>
</Sheet>
<Sheet>
<ROI>5350</ROI>
<TPI>857</TPI>
</Sheet>
<Sheet>
<ROI>5713</ROI>
<TPI>857</TPI>
</Sheet>
</set>
</Sheets>
like, group 4 sheets to one set and other 4 to one set and finally rest of them to one set

If you have XQuery 3.0 available, you could use a tumbling window to achieve this quite easily:
xquery version "3.0";
let $group-size := 4 (: set your group size here :)
return
<Sheets>
{
for tumbling window $window in /Sheets/Sheet
start at $start when fn:true()
end at $end when $end - $start eq $group-size - 1
return
<set>{$window}</set>
}
</Sheets>
Otherwise, if you only have XQuery 1.0 available to you, then you can do it with a simple FLWOR expression and positional predicates:
xquery version "1.0";
let $group-size := 4 (: set your group size here :)
return
<Sheets>
{
for $group in (1 to round(count(/Sheets/Sheet) div $group-size) cast as xs:integer)
let $start := (1 * ($group - 1) * $group-size) + 1
let $end := $group * $group-size
return
<set>{/Sheets/Sheet[position() ge $start][position() le $end]}</set>
}
</Sheets>

You could use subsequence() and call a function recursively.
Example...
XML Input
<Sheets>
<Sheet>
<ROI>5350</ROI>
<TPI>830</TPI>
</Sheet>
<Sheet>
<ROI>5459</ROI>
<TPI>830</TPI>
</Sheet>
<Sheet>
<ROI>5350</ROI>
<TPI>856</TPI>
</Sheet>
<Sheet>
<ROI>5678</ROI>
<TPI>856</TPI>
</Sheet>
<Sheet>
<ROI>17473</ROI>
<TPI>856</TPI>
</Sheet>
<Sheet>
<ROI>5350</ROI>
<TPI>857</TPI>
</Sheet>
<Sheet>
<ROI>5713</ROI>
<TPI>857</TPI>
</Sheet>
</Sheets>
XQuery ($groupSize passed as 4)
declare variable $groupSize external;
declare function local:group($set as node()*, $size as xs:integer) as item()* {
<set>{subsequence($set,1,$size)}</set>,
if (count($set)>$groupSize) then
local:group(subsequence($set,$groupSize+1),$groupSize)
else
()
};
<Sheets>{local:group(/*/*,$groupSize)}</Sheets>
XML Output
<Sheets>
<set>
<Sheet>
<ROI>5350</ROI>
<TPI>830</TPI>
</Sheet>
<Sheet>
<ROI>5459</ROI>
<TPI>830</TPI>
</Sheet>
<Sheet>
<ROI>5350</ROI>
<TPI>856</TPI>
</Sheet>
<Sheet>
<ROI>5678</ROI>
<TPI>856</TPI>
</Sheet>
</set>
<set>
<Sheet>
<ROI>17473</ROI>
<TPI>856</TPI>
</Sheet>
<Sheet>
<ROI>5350</ROI>
<TPI>857</TPI>
</Sheet>
<Sheet>
<ROI>5713</ROI>
<TPI>857</TPI>
</Sheet>
</set>
</Sheets>

Related

Importing XSD and data into R

I generated a XML output from a database (MSSQL2014) and now would like to consume the data as well as the XSD schema information into a R data frame.
Data Source: MSSQL2014 - AdventureWorks2014 database
Query executed:
select top 1 *
from person.person as p
join person.EmailAddress as ea on p.businessEntityID = ea.businessentityID
join person.PersonPhone as pphone on p.businessEntityID = pphone.businessentityID
for XML AUTO, ELEMENTS, XMLSCHEMA('person');
Below is the File generate. I tried this R code to import but it is unsuccessful. Does anyone have a guide/tip to point me to the right direction?
RCode:
library(XML)
(xml_data <- xmlParse(gsub(" ", "", "C:\\dissertation\\smta\\indata\\01_Source_Query.XML", fixed = TRUE), asText = TRUE))
xml_attrib <- xpathSApply(doc=xml, path="//person", xmlAttrs)
df2 <- data.frame(t(xml_attrib))
df2
<xsd:schema targetNamespace="person" xmlns:schema="person" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:sqltypes="http://schemas.microsoft.com/sqlserver/2004/sqltypes" elementFormDefault="qualified">
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/sqltypes" schemaLocation="http://schemas.microsoft.com/sqlserver/2004/sqltypes/sqltypes.xsd" />
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo" />
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactRecord" />
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes" />
<xsd:import namespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/IndividualSurvey" />
<xsd:element name="p">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="BusinessEntityID" type="sqltypes:int" />
<xsd:element name="PersonType">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="2" /></xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="NameStyle" type="sqltypes:bit" sqltypes:sqlTypeAlias="[AdventureWorks2014].[dbo].[NameStyle]" />
<xsd:element name="Title" minOccurs="0">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="8" /></xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="FirstName">
<xsd:simpleType sqltypes:sqlTypeAlias="[AdventureWorks2014].[dbo].[Name]">
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="50" /></xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="MiddleName" minOccurs="0">
<xsd:simpleType sqltypes:sqlTypeAlias="[AdventureWorks2014].[dbo].[Name]">
<xsd:restri ction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="50" /></xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="LastName">
<xsd:simpleType sqltypes:sqlTypeAlias="[AdventureWorks2014].[dbo].[Name]">
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="50" /></xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="Suffix" minOccurs="0">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="10" /></xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="EmailPromotion" type="sqltypes:int" />
<xsd:element name="AdditionalContactInfo" minOccurs="0">
<xsd:complexType sqltypes:xmlSchemaCollection="[AdventureWorks2014].[Person].[AdditionalContactInfoSchemaCollection]">
<xsd:complexContent>
<xsd:restriction base="sqltypes:xml">
<xsd:sequence>
<xsd:any processContents="strict" minOccurs="0" maxOccurs="unbounded" namespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactInfo http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactRecord http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/ContactTypes"
/></xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd:element name="Demographics" minOccurs="0">
<xsd:complexType sqltypes:xmlSchemaCollection="[AdventureWorks2014].[Person].[IndividualSurveySchemaCollection]">
<xsd:complexContent>
<xsd:restriction base="sqltypes:xml">
<xsd:sequence>
<xsd:any processContents="strict" minOccurs="0" maxOccurs="unbounded" namespace="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/IndividualSurvey" /></xsd:sequence>
</xsd:restriction>
</xsd:complexContent>
</xsd:complexType>
</xsd:element>
<xsd :element name="rowguid" type="sqltypes:uniqueidentifier" />
<xsd:element name="ModifiedDate" type="sqltypes:datetime" />
<xsd:element ref="schema:ea" minOccurs="0" maxOccurs="unbounded" /></xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="ea">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="BusinessEntityID" type="sqltypes:int" />
<xsd:element name="EmailAddressID" type="sqltypes:int" />
<xsd:element name="EmailAddress" minOccurs="0">
<xsd:simpleType>
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="50" /></xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="rowguid" type="sqltypes:uniqueidentifier" />
<xsd:element name="ModifiedDate" type="sqltypes:datetime" />
<xsd:element ref="schema:pphone" minOccurs="0" maxOccurs="unbounded" /></xsd:sequence>
</xsd:complexType>
</xsd:element>
<xsd:element name="pphone">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="BusinessEntityID" type="sqltypes:int" />
<xsd:element name="PhoneNumber">
<xsd:simpleType sqltypes:sqlTypeAlias="[AdventureWorks2014].[dbo].[Phone]">
<xsd:restriction base="sqltypes:nvarchar" sqltypes:localeId="1033" sqltypes:sqlCompareOptions="IgnoreCase IgnoreKanaType IgnoreWidth" sqltypes:sqlSortId="52">
<xsd:maxLength value="25" /></xsd:restriction>
</xsd:simpleType>
</xsd:element>
<xsd:element name="PhoneNumberTypeID" type="sqltypes:int" />
<xsd:element name="ModifiedDate" type="sqltypes:datetime" /></xsd:sequence>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<p xmlns="person">
<BusinessEntityID>1</BusinessEntityID>
<PersonType>EM</PersonType>
<NameStyle>0</NameStyle>
<FirstName>Ken</FirstName>
<MiddleName>J</MiddleName>
<LastName>Sánchez</LastName>
<EmailPromotion>0</EmailPromotion>
<Demographics>
<IndividualSurvey xmlns="http://schemas.microsoft.com/sqlserver/2004/07/adventure-works/IndividualSurvey">
<TotalPurchaseYTD>0</TotalPurchaseYTD>
</IndividualSurvey>
</Demographics>
<rowguid>92C4279F-1207-48A3-8448-4636514EB7E2</rowgu id>
<ModifiedDate>2009-01-07T00:00:00</ModifiedDate>
<ea>
<BusinessEntityID>1</BusinessEntityID>
<EmailAddressID>1</EmailAddressID>
<EmailAddress>ken0#adventure-works.com</EmailAddress>
<rowguid>8A1901E4-671B-431A-871C-EADB2942E9EE</rowguid>
<ModifiedDate>2009-01-07T00:00:00</ModifiedDate>
<pphone>
<BusinessEntityID>1</BusinessEntityID>
<PhoneNumber>697-555-0142</PhoneNumber>
<PhoneNumberTypeID>1</PhoneNumberTypeID>
<ModifiedDate>2009-01-07T00:00:00</ModifiedDate>
</pphone>
</ea>
</p>
I prefer the rest/xml2 package for parsing files.
library(xml2)
library(rvest)
page<-read_html("C:\\dissertation\\smta\\indata\\01_Source_Query.XML")
persons<-html_nodes(page, xpath = "//p")
fieldnames<-xml_name(xml_find_all(persons, ".//*"))
fields<-xml_text(xml_find_all(persons, ".//*"))
df<-data.frame(fieldnames, fields)
The file seems to be interested as html. The code above reads the data file finds the paragraph tag for the persons and extracts the field names and values and places them into a data frame. If there are multiple persons in your file then the lines defining field names and values will need to be vectorized (most likely with supply). Some clean-up is required to remove a few extraneous rows added to the final data frame.
Good luck.

Insert Image into a Column Series Telerik

I need to add an image in a specific Column chart, but I have no idea how can I insert the image, any idea, tutorial ?
I am using the RadHtmlChart
this is my code:
<telerik:RadHtmlChart ID="Chart" runat="server" Width="680" Height="500">
<PlotArea>
<XAxis>
<LabelsAppearance>
<TextStyle Color="white" FontFamily="Arial" FontSize="13" />
</LabelsAppearance>
</XAxis>
<YAxis MinValue="0" >
<LabelsAppearance DataFormatString="${0:0,0}">
<TextStyle Color="white" FontFamily="Arial" FontSize="12" />
</LabelsAppearance>
</YAxis>
<Series>
<telerik:ColumnSeries Name="Garantías Vigentes" Stacked="true">
<LabelsAppearance Position="Center" DataFormatString="${0:0,0}">
<TextStyle Color="Black" FontFamily="Arial" Bold="True" FontSize="18" />
</LabelsAppearance>
<Appearance>
<FillStyle BackgroundColor="#87cb50"></FillStyle>
</Appearance>
<SeriesItems>
</SeriesItems>
</telerik:ColumnSeries>
</Series>
<Series>
<telerik:ColumnSeries Name="Saldo Vigente" Stacked="true">
<LabelsAppearance Position="Center" DataFormatString="${0:0,0}">
<TextStyle Color="Black" FontFamily="Arial" Bold="True" FontSize="18" />
</LabelsAppearance>
<Appearance>
<FillStyle BackgroundColor="#8DB4E2"></FillStyle>
</Appearance>
<SeriesItems>
<telerik:CategorySeriesItem Y="0"></telerik:CategorySeriesItem>
</SeriesItems>
</telerik:ColumnSeries>
<telerik:ColumnSeries Name="" > //In this Column I need to insert the image
<LabelsAppearance Position="Center" DataFormatString="${0:0,0}">
<TextStyle Color="Black" FontFamily="Arial" Bold="True" FontSize="0" />
</LabelsAppearance>
<Appearance>
</Appearance>
<SeriesItems>
<telerik:CategorySeriesItem Y="0"></telerik:CategorySeriesItem>
</SeriesItems>
</telerik:ColumnSeries>
</Series>
</PlotArea>
<Legend>
<Appearance Position="Bottom"><TextStyle Color="white" FontFamily="Arial" FontSize="20" Bold="True"/></Appearance>
</Legend>
</telerik:RadHtmlChart>
I found in the forums Telerik but I can not find anything similar.
thanks for yours comments
I don't see where you have attempted to add an image, but this would be possible only inside a series tooltip, because this is the only place in the chart that renders HTML, the rest is SVG/VML.
Take a look at these articles to see how to add HTML to your tooltips and bind it to database data, if needed (e.g., for the src attribute):
http://www.telerik.com/help/aspnet-ajax/htmlchart-client-templates-for-tooltips-and-labels.html
http://www.telerik.com/help/aspnet-ajax/htmlchart-client-templates-for-tooltips-and-labels-execute-javascript-and-display-html.html

Bpel arrays transformation foreach

I have a bpel process which receive an array and output another one.
The thing is, I need to get the first one elements, populate the second one and add some for elements in the second one.
My first one array is from this kind of object:
<xsd:complexType name="comment_A">
<xsd:sequence>
<xsd:element name="id" type="xsd:int"/>
<xsd:element name="username" type="xsd:string"/>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="picture" type="xsd:base64Binary"/>
<xsd:element name="date" type="xsd:string"/>
<xsd:element name="hour" type="xsd:string"/>
<xsd:element name="bus-line" type="xsd:string"/>
<xsd:element name="bus-number" type="xsd:integer"/>
<xsd:element name="description" type="xsd:string"/>
<xsd:element name="rate" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
My second one:
<xsd:complexType name="comment_B">
<xsd:sequence>
<xsd:element name="id" type="xsd:int"/>
<xsd:element name="username" type="xsd:string"/>
<xsd:element name="name" type="xsd:string"/>
<xsd:element name="picture" type="xsd:base64Binary"/>
<xsd:element name="date" type="xsd:string"/>
<xsd:element name="hour" type="xsd:string"/>
<xsd:element name="bus-line" type="xsd:string"/>
<xsd:element name="bus-number" type="xsd:integer"/>
<xsd:element name="description" type="xsd:string"/>
<xsd:element name="rate" type="xsd:int"/>
<xsd:element name="type-comment" type="xsd:string"/>
<xsd:element name="liked-number" type="xsd:int"/>
</xsd:sequence>
</xsd:complexType>
So first, I tried iterate over the first array to populate the second one with properties which both have in common. I tried use forEach element.
My code seems like this:
<forEach parallel="yes" counterName="c" name="forEachComment">
<startCounterValue>1</startCounterValue>
<finalCounterValue>count($comments.VwCommentCollection/ns3:VwComment)</finalCounterValue>
<scope name="Scope1">
<assign name="assignResult">
<extensionAssignOperation>
<bpelx:copyList>
<bpelx:from>$comments.VwCommentCollection[$c]</bpelx:from>
<bpelx:to>$outputVariable.payload</bpelx:to>
</bpelx:copyList>
</extensionAssignOperation>
<copy>
<from>$comments.VwCommentCollection[$c]/ns3:VwComment/ns3:id</from>
<to>$outputVariable.payload/ns2:comment/ns2:id</to>
</copy>
</assign>
</scope>
</forEach>
I tried do this first just with id element for a test, however when the comment_A array has size greater than 1, I receive an exception
$comment is my variable which comment_A array
I found a solution following this Brazilian blog: http://blog.iprocess.com.br/2012/09/oracle-soa-suite-11g-uso-da-atividade-assign-no-bpel/
I used append opperation inside BPEL

How do I use SOAP::Lite with WCF?

I'm just trying to get started with WCF. It sounds like it is supposed to be super simple, but using a simple API like SOAP::Lite, I am having trouble getting anything to work. There are a lot of out dated examples in the googlesphere, and I have tried many of them to no avail. So now I am trying to break down the problem to its lowest level. I created the WCF app generated by the Visual Web Developer 2008 Express template. This is its service contract:
[ServiceContract]
public interface IService1
{
[OperationContract]
string GetData(int value);
[OperationContract]
CompositeType GetDataUsingDataContract(CompositeType composite);
// TODO: Add your service operations here
}
// Use a data contract as illustrated in the sample below to add composite types to service operations.
[DataContract]
public class CompositeType
{
bool boolValue = true;
string stringValue = "Hello ";
[DataMember]
public bool BoolValue
{
get { return boolValue; }
set { boolValue = value; }
}
[DataMember]
public string StringValue
{
get { return stringValue; }
set { stringValue = value; }
}
}
I started it up in debug mode and tried to make contact. Doing so with a browser using the debug url http://localhost:59315/Service1.svc gives me a page saying this:
You have created a service.
To test this service, you will need to create a client and use it to
call the service. You can do this using the svcutil.exe tool from the
command line with the following syntax:
svcutil.exe http://localhost:59315/Service1.svc?wsdl
So, then I brows to that wsdl and get this:
<wsdl:definitions name="Service1" targetNamespace="http://tempuri.org/">
<wsp:Policy wsu:Id="WSHttpBinding_IService1_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SymmetricBinding>
<wsp:Policy>
<sp:ProtectionToken>
<wsp:Policy>
<sp:SecureConversationToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:RequireDerivedKeys/>
<sp:BootstrapPolicy>
<wsp:Policy>
<sp:SignedParts>
<sp:Body/>
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>
</sp:SignedParts>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
<sp:SymmetricBinding>
<wsp:Policy>
<sp:ProtectionToken>
<wsp:Policy>
<sp:SpnegoContextToken sp:IncludeToken="http://schemas.xmlsoap.org/ws/2005/07/securitypolicy/IncludeToken/AlwaysToRecipient">
<wsp:Policy>
<sp:RequireDerivedKeys/>
</wsp:Policy>
</sp:SpnegoContextToken>
</wsp:Policy>
</sp:ProtectionToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
<sp:EncryptSignature/>
<sp:OnlySignEntireHeadersAndBody/>
</wsp:Policy>
</sp:SymmetricBinding>
<sp:Wss11>
<wsp:Policy>
<sp:MustSupportRefKeyIdentifier/>
<sp:MustSupportRefIssuerSerial/>
<sp:MustSupportRefThumbprint/>
<sp:MustSupportRefEncryptedKey/>
</wsp:Policy>
</sp:Wss11>
<sp:Trust10>
<wsp:Policy>
<sp:MustSupportIssuedTokens/>
<sp:RequireClientEntropy/>
<sp:RequireServerEntropy/>
</wsp:Policy>
</sp:Trust10>
</wsp:Policy>
</sp:BootstrapPolicy>
</wsp:Policy>
</sp:SecureConversationToken>
</wsp:Policy>
</sp:ProtectionToken>
<sp:AlgorithmSuite>
<wsp:Policy>
<sp:Basic256/>
</wsp:Policy>
</sp:AlgorithmSuite>
<sp:Layout>
<wsp:Policy>
<sp:Strict/>
</wsp:Policy>
</sp:Layout>
<sp:IncludeTimestamp/>
<sp:EncryptSignature/>
<sp:OnlySignEntireHeadersAndBody/>
</wsp:Policy>
</sp:SymmetricBinding>
<sp:Wss11>
<wsp:Policy>
<sp:MustSupportRefKeyIdentifier/>
<sp:MustSupportRefIssuerSerial/>
<sp:MustSupportRefThumbprint/>
<sp:MustSupportRefEncryptedKey/>
</wsp:Policy>
</sp:Wss11>
<sp:Trust10>
<wsp:Policy>
<sp:MustSupportIssuedTokens/>
<sp:RequireClientEntropy/>
<sp:RequireServerEntropy/>
</wsp:Policy>
</sp:Trust10>
<wsaw:UsingAddressing/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="WSHttpBinding_IService1_GetData_Input_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SignedParts>
<sp:Body/>
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>
</sp:SignedParts>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="WSHttpBinding_IService1_GetData_output_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SignedParts>
<sp:Body/>
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>
</sp:SignedParts>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="WSHttpBinding_IService1_GetDataUsingDataContract_Input_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SignedParts>
<sp:Body/>
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>
</sp:SignedParts>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsp:Policy wsu:Id="WSHttpBinding_IService1_GetDataUsingDataContract_output_policy">
<wsp:ExactlyOne>
<wsp:All>
<sp:SignedParts>
<sp:Body/>
<sp:Header Name="To" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="From" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="FaultTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="ReplyTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="MessageID" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="RelatesTo" Namespace="http://www.w3.org/2005/08/addressing"/>
<sp:Header Name="Action" Namespace="http://www.w3.org/2005/08/addressing"/>
</sp:SignedParts>
<sp:EncryptedParts>
<sp:Body/>
</sp:EncryptedParts>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>
<wsdl:types>
<xsd:schema targetNamespace="http://tempuri.org/Imports">
<xsd:import schemaLocation="http://localhost:59315/Service1.svc?xsd=xsd0" namespace="http://tempuri.org/"/>
<xsd:import schemaLocation="http://localhost:59315/Service1.svc?xsd=xsd1" namespace="http://schemas.microsoft.com/2003/10/Serialization/"/>
<xsd:import schemaLocation="http://localhost:59315/Service1.svc?xsd=xsd2" namespace="http://schemas.datacontract.org/2004/07/RossDominosService"/>
</xsd:schema>
</wsdl:types>
<wsdl:message name="IService1_GetData_InputMessage">
<wsdl:part name="parameters" element="tns:GetData"/>
</wsdl:message>
<wsdl:message name="IService1_GetData_OutputMessage">
<wsdl:part name="parameters" element="tns:GetDataResponse"/>
</wsdl:message>
<wsdl:message name="IService1_GetDataUsingDataContract_InputMessage">
<wsdl:part name="parameters" element="tns:GetDataUsingDataContract"/>
</wsdl:message>
<wsdl:message name="IService1_GetDataUsingDataContract_OutputMessage">
<wsdl:part name="parameters" element="tns:GetDataUsingDataContractResponse"/>
</wsdl:message>
<wsdl:portType name="IService1">
<wsdl:operation name="GetData">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/GetData" message="tns:IService1_GetData_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IService1/GetDataResponse" message="tns:IService1_GetData_OutputMessage"/>
</wsdl:operation>
<wsdl:operation name="GetDataUsingDataContract">
<wsdl:input wsaw:Action="http://tempuri.org/IService1/GetDataUsingDataContract" message="tns:IService1_GetDataUsingDataContract_InputMessage"/>
<wsdl:output wsaw:Action="http://tempuri.org/IService1/GetDataUsingDataContractResponse" message="tns:IService1_GetDataUsingDataContract_OutputMessage"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="WSHttpBinding_IService1" type="tns:IService1">
<wsp:PolicyReference URI="#WSHttpBinding_IService1_policy"/>
<soap12:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="GetData">
<soap12:operation soapAction="http://tempuri.org/IService1/GetData" style="document"/>
<wsdl:input>
<wsp:PolicyReference URI="#WSHttpBinding_IService1_GetData_Input_policy"/>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsp:PolicyReference URI="#WSHttpBinding_IService1_GetData_output_policy"/>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
<wsdl:operation name="GetDataUsingDataContract">
<soap12:operation soapAction="http://tempuri.org/IService1/GetDataUsingDataContract" style="document"/>
<wsdl:input>
<wsp:PolicyReference URI="#WSHttpBinding_IService1_GetDataUsingDataContract_Input_policy"/>
<soap12:body use="literal"/>
</wsdl:input>
<wsdl:output>
<wsp:PolicyReference URI="#WSHttpBinding_IService1_GetDataUsingDataContract_output_policy"/>
<soap12:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="Service1">
<wsdl:port name="WSHttpBinding_IService1" binding="tns:WSHttpBinding_IService1">
<soap12:address location="http://localhost:59315/Service1.svc"/>
<wsa10:EndpointReference>
<wsa10:Address>http://localhost:59315/Service1.svc</wsa10:Address>
<Identity>
<Dns>localhost</Dns>
</Identity>
</wsa10:EndpointReference>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
Nothing too crazy (other than SOAP itself)... Anyway, now I try a simple SOAP::Lite app:
#!/cygdrive/C/Perl64/bin/perl.exe -w
use strict;
use warnings;
use Data::Dumper;
use SOAP::Lite +trace => [ transport => sub {
my ($in) = #_;
if ( ref($in) eq "HTTP::Request") {
print( "REQUEST\n" . $in->content() . "\nEND REQUEST\n" );
}
elsif ( ref($in) eq "HTTP::Response") {
print( "RESPONSE\n" . $in->content() . "\nEND RESPONSE\n" );
}
} ];
my $server = 'http://localhost:59315/Service1.svc';
my $url = "$server?wsdl";
my $xmlns = 'http://schemas.datacontract.org/2004/07/RossDominosService';
# Setup Network Connection
my $service = SOAP::Lite
->ns( $url )
->proxy( $server )
->on_fault( sub {
my ($soap, $res) = #_;
die ref $res ? $res->faultstring() : $soap->transport()->status(), "\n";
} );
;
print( Dumper( $service ) );
eval {
print( "making request\n" );
my $response = $service->GetData(
SOAP::Data->new( name => 'value', value => 5 )
);
print( "got response:\n$response\n" );
};
if ( $# ) {
print( "failed:\n**************************\n$#\n*****************************\n" );
}
Which from the debug is issuing this SOAP request:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:namesp1="http://localhost:59315/Service1.svc?wsdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<namesp1:GetData>
<value xsi:type="xsd:int">5</value>
</namesp1:GetData>
</soap:Body>
</soap:Envelope>
But the response comes back with:
failed:
**************************
415 Unsupported Media Type
*****************************
What is going on? This is the "Hello, World!" of SOAP apps and I cant figure it out.
-----------------------UPDATE-------------------------------
I found that I need to change the binding from its default of wsHttpBinding to:
<endpoint address="" binding="basicHttpBinding"
contract="RossDominosService.IService1">
Now it appears to connect, but I am getting this new error:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/ws/2005/05/addressing/none">a:ActionNotSupported</faultcode>
<faultstring xml:lang="en-US">The message with Action 'http://tempuri.org/GetData' cannot be processed at the receiver, due to a ContractFilter mismatch at the EndpointDispatcher. This may be because of either a contract mismatch (mismatched Actions between sender and receiver) or a binding/security mismatch between the sender and the receiver. Check that sender and receiver have the same contract and the same binding (including security requirements, e.g. Message, Transport, None).</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
It doesn't seem like this should be so hard...
-----------------------UPDATE-------------------------------
Got it! After some more tinkering, and some assistance from soapUI, I figured out that the action needs to be modified so that it is:
<namespace>/<serviceContract>/<method>
in this case:
http://tempuri.org/IService1/GetData
When using SOAP::Lite, the default SOAPAction is
<namespace>#<method>
So you have to modify your soap object thusly:
$soap->on_action( sub { sprintf( '%sIService1/%s', #_ ) } );
I will write up the answer below so we can close this question...
This is how I accomplished getting a WCF web service up and running with a perl SOAP::Lite client. Note that I am using Visual Web Developer Express 2008 and perl 5.14 with SOAP::Lite 0.715.
Open up Visual Web Developer
File -> New Project...
Visual C# -> Web
WCF Service Application
Name: WcfService1
Location:
Solution: new solution
Solution Name:
Open Web.config
change <compilation debug="false"> to <compilation debug="true">
change <endpoint address="" binding="wsHttpBinding" contract="WcfService1.IService1"> to <endpoint address="" binding="basicHttpBinding" contract="WcfService1.IService1">
Open Service1.svc.cs
press f5 (to start debugging)
Now a browser window should pop up opened to your Service page. Take note of the port in the url, you will need it for the client. Then create this script:
#!/cygdrive/C/Perl64/bin/perl.exe -w
use strict;
use warnings;
use Data::Dumper;
use SOAP::Lite +trace => [ transport => sub {
my ($in) = #_;
if ( ref($in) eq "HTTP::Request") {
print( "**** REQUEST ****\n" . $in->content() . "\n**** END REQUEST ****\n" );
}
elsif ( ref($in) eq "HTTP::Response") {
print( "**** RESPONSE ****\n" . $in->content() . "\n**** END RESPONSE ****\n" );
}
} ];
my $port = 63181;
my $server = "http://localhost:$port/Service1.svc";
my $namespace = 'http://tempuri.org/';
# Setup Network Connection
my $service = SOAP::Lite
->ns( $namespace, 'my' )
->proxy( $server )
->on_action( sub {
my $action = sprintf( '%sIService1/%s', #_ );
print( "action: '$action'\n" );
return $action;
} );
print( Dumper( $service ) );
eval {
print( "making request\n" );
my $response = $service->GetData(
SOAP::Data->new( prefix => 'my', name => 'value', value => 5 )
);
print( "got response:\n$response\n" );
};
if ( $# ) {
print( "failed:\n**************************\n$#\n*****************************\n" );
}
You will need to change the port number to match your port number. Also, I left in a bunch of the debug code so you can see what is going on.
I hope this helps someone else.

Unmarshal xhtml as string using xsd

I'm trying to unmarshal a large xhtml document using XSD's and jaxb. I've got everything working except for one part, which contains pure html. Here is an example of the xhtml I'm getting (I am able to grab every element except the "content"):
<feed xmlns="http://www.w3.org/2005/Atom">
<title type="text">...</title>
<id>...</id>
<updated>...</updated>
<entry>
<id>...</id>
<title type="text">...</title>
<updated>...</updated>
<author>
<name>...</name>
</author>
<content type="xhtml"><div xmlns="http://www.w3.org/1999/xhtml">
<div>{html...}<div>{html...}</div>/<div>/<div>
</content>
</entry>
</feed>
Here's an expansion of the xsd file:
<xsd:complexType name="ApCategoriesJAXB" >
<xsd:sequence>
<xsd:element name="id" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>
<xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>
<xsd:element name="updated" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>
<xsd:element name="link" type="tns:ApLinkJAXB" minOccurs="0"></xsd:element>
<xsd:element name="entry" type="tns:ApEntryJAXB" minOccurs="0" maxOccurs="unbounded"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ApEntryJAXB">
<xsd:sequence>
<xsd:element name="id" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>
<xsd:element name="name" type="xsd:string" minOccurs="0"></xsd:element>
<xsd:element name="title" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>
<xsd:element name="updated" type="xsd:string" minOccurs="1" maxOccurs="1"></xsd:element>
<xsd:element name="author" type="tns:ApAuthorJAXB" minOccurs="0"></xsd:element>
<xsd:element name="link" type="tns:ApLinkJAXB" minOccurs="0"></xsd:element>
<xsd:element name="category" type="tns:ApCategoryJAXB" minOccurs="0"></xsd:element>
<xsd:element name="content" type="tns:ApContentJAXB" minOccurs="0"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ApCategoryJAXB" >
<xsd:sequence></xsd:sequence>
<xsd:attribute name="term" type="xsd:string" />
<xsd:attribute name="label" type="xsd:string" />
<xsd:attribute name="scheme" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="ApContentJAXB" >
<xsd:sequence>
<xsd:element name="div" type="tns:ApDivJAXB" minOccurs="0" maxOccurs="unbounded"></xsd:element>
</xsd:sequence>
</xsd:complexType>
<xsd:complexType name="ApDivJAXB" >
<xsd:sequence>
<xsd:any namespace="http://www.w3.org/2005/Atom" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
</xsd:sequence>
</xsd:complexType>
I have tried every combination of nested xsd elements, complexTypes, xsd:any etc etc and cannot seem to get this "content" value no matter what I try. I am happy to take all the html as a string, or unmarshal it into an object.
Thank you in advance for any thoughts.
** I've edited the xsd part to include relevant parts. I've tried both nesting the "any" element in the "div" complexType as seen, as well as skipping the "div" complexType altogether.
Thanks again.
If you want <content> to have a type of xsd:string, you need to encode or otherwise escape the HTML. You could use CDATA sections, Base64 encoding, or escape all the entities (e.g. < to <, etc.).
Otherwise, xsd:any should work. Can you provide a more complete example of your XSD when you tried this?

Resources