Exclude Result Element in SOAP Call - c#

I'm trying to exclude the result element being returned from my SOAP call but I cant seem to get it excluded. I then set up this simple call which returns xml data from a file. I need the result element removed as it wont validate against the schema. I've tried adding the SoapParameterStyle.Bare but i still get the node
[WebMethod]
[SoapDocumentMethod(ParameterStyle = SoapParameterStyle.Bare)]
[return: System.Xml.Serialization.XmlElement(IsNullable = true)]
public XmlDocument TestMethod(XmlDocument p_xmlDoc)
{
XmlDocument xmldoc = new XmlDocument();
string sResponsePath = ConfigurationManager.AppSettings["FileDirectory"] + ConfigurationManager.AppSettings["GetOrders"];
string sXMLResponse = File.ReadAllText(sResponsePath);
xmldoc.LoadXml(sXMLResponse);
return xmldoc;
}
Here is the first few nodes that would be returned from that SOAP call and as you can see the TestMethodResult is returned under the Body element:
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<TestMethodResult xmlns="http://tempuri.org/">
<ns0:TestMethodResponse xmlns:ns0="http://eibdigital.co.uk/citb/EibOrderInterface">
<ns0:TestMethodResult>

You can run simple XSLT transformation on XML. Example program
string xmlInput = #"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"">
<soap:Body>
<TestMethodResult xmlns=""http://tempuri.org/"">
<ns0:TestMethodResponse xmlns:ns0=""http://eibdigital.co.uk/citb/EibOrderInterface"">
<ns0:TestMethodResult>
</ns0:TestMethodResult>
</ns0:TestMethodResponse>
</TestMethodResult>
</soap:Body>
</soap:Envelope>";
string xslInput = #"<?xml version=""1.0"" encoding=""UTF-8""?>
<xsl:stylesheet xmlns:xsl=""http://www.w3.org/1999/XSL/Transform""
xmlns:tmp=""http://tempuri.org/""
version=""1.0"">
<!--identity template, copies all content by default-->
<xsl:template match=""#*|node()"">
<xsl:copy>
<xsl:apply-templates select=""#*|node()""/>
</xsl:copy>
</xsl:template>
<!--don't generate content for the <b>, just apply-templates to it's children-->
<xsl:template match=""tmp:TestMethodResult"">
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>";
string output = String.Empty;
using (StringReader srt = new StringReader(xslInput))
using (StringReader sri = new StringReader(xmlInput))
{
using (XmlReader xrt = XmlReader.Create(srt))
using (XmlReader xri = XmlReader.Create(sri))
{
XslCompiledTransform xslt = new XslCompiledTransform();
xslt.Load(xrt);
using (StringWriter sw = new StringWriter())
using (XmlWriter xwo = XmlWriter.Create(sw, xslt.OutputSettings))
{
xslt.Transform(xri, xwo);
output = sw.ToString();
}
}
}
And the output at the end contains your xml (without TestMethodResult xmlns="http://tempuri.org/")
This answer was inspired by two other SOF questions:
How do I remove the outermost wrappers using xslt?
How to transform XML as a string w/o using files in .NET?
Also if you one to stick with the XML files loaded from disk you can do it like this:
string sResponsePath = ConfigurationManager.AppSettings["FileDirectory"] + ConfigurationManager.AppSettings["GetOrders"];
string xsltPath = "Drive://your/path/to/xslt/file.xslt";
XPathDocument myXPathDoc = new XPathDocument(sResponsePath);
XslCompiledTransform myXslTrans = new XslCompiledTransform();
myXslTrans.Load(xsltPath);
var ms = new MemoryStream();
XmlTextWriter myWriter = new XmlTextWriter(ms, Encoding.UTF8);
myXslTrans.Transform(myXPathDoc, null, myWriter);
ms.Position = 0;
var sr = new StreamReader(ms);
var myStr = sr.ReadToEnd();
compare:
How to apply an XSLT Stylesheet in C#

Related

LoadXML Add Parameters

I'm doing LoadXML, but I need to add a field from the form but I couldn't,
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdefg</Kodu>
<Sifre>123456789</Sifre>
<HesKodu>TXBHesKodu.Text</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
return soapEnvelopeDocument;
I need to add the TXBHESKodu.Text from the form to the <HesKodu> field here.
I think I couldn't make the upper quotation marks added into the file.
Can you show me how to do it?
Here are two ways you could do that. The first being the simplest. Just use string formatting like this (note the $ sign before your # sign):
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
$#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdefg</Kodu>
<Sifre>123456789</Sifre>
<HesKodu>{TXBHesKodu.Text}</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
The second method uses the XML Dom to add the text into the element. We find the element using the XPath syntax:
var xmlDocument = GetXmlDocument(#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdefg</Kodu>
<Sifre>123456789</Sifre>
<HesKodu></HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
XmlNode HesKodu = xmlDocument.SelectSingleNode("//Servis5001/HesKodu");
HesKodu.InnerText = TXBHesKodu.Text;
You would be better off letting Visual Studio handle all the SOAP stuff for you. Take a look at adding a reference to a SOAP Web Service Reference (right click on project and Add => Web Service Reference). You can simply enter the url with ?wsdl at the end and it will generate everything you need to consume the web service.
You can use the url in a webbrowser too. If you have access to the service you can simply enter the url in the addressbar and press Enter. It should give you a description of the service and how to consume it.
Method Usage Error When I Want to Add TXT HesKodu.Text
private static XmlDocument CreateSoapEnvelope()
{
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
$#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdef</Kodu>
<Sifre>abcdef</Sifre>
<HesKodu>{TXBHesKodu.Text}</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
return soapEnvelopeDocument;
}
SOAP Whatever I Use My Blog Is All The Code Is As Below, Maybe If You Want To See It
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Xml;
namespace TOBBHesKoduSorgulama
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void BTNSorgula_Click(object sender, EventArgs e)
{
var _url = "https://kpsoda.tobb.org.tr/hesservis.php?wsdl";
var _action = "https://kpsoda.tobb.org.tr/hesservis.php?op=Servis5001";
var result = "";
XmlDocument soapEnvelopeXml = CreateSoapEnvelope();
HttpWebRequest webRequest = CreateWebRequest(_url, _action);
InsertSoapEnvelopeIntoWebRequest(soapEnvelopeXml, webRequest);
// begin async call to web request.
IAsyncResult asyncResult = webRequest.BeginGetResponse(null, null);
// suspend this thread until call is complete. You might want to
// do something usefull here like update your UI.
asyncResult.AsyncWaitHandle.WaitOne();
// get the response from the completed web request.
string soapResult;
using (WebResponse webResponse = webRequest.EndGetResponse(asyncResult))
{
using (StreamReader rd = new StreamReader(webResponse.GetResponseStream()))
{
soapResult = rd.ReadToEnd();
}
result = soapResult;
Console.Write(soapResult);
}
}
private static HttpWebRequest CreateWebRequest(string url, string action)
{
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(url);
webRequest.Headers.Add("SOAPAction", action);
webRequest.ContentType = "text/xml;charset=\"utf-8\"";
webRequest.Accept = "text/xml";
webRequest.Method = "POST";
return webRequest;
}
private static XmlDocument CreateSoapEnvelope()
{
XmlDocument soapEnvelopeDocument = new XmlDocument();
soapEnvelopeDocument.LoadXml(
$#"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Servis5001>
<Kodu>abcdef</Kodu>
<Sifre>abcdef</Sifre>
<HesKodu>{TXBHesKodu.Text}</HesKodu>
</Servis5001>
</soap:Body>
</soap:Envelope>");
return soapEnvelopeDocument;
}
private static void InsertSoapEnvelopeIntoWebRequest(XmlDocument soapEnvelopeXml, HttpWebRequest webRequest)
{
using (Stream stream = webRequest.GetRequestStream())
{
soapEnvelopeXml.Save(stream);
}
}
}
}
I also tried the Service References Process But I Didn't Know How To Request
string Kodu = "Kodu";
string Sifre = "Sifre";
string HesKodu = "HesKodu";
TOBBHesKoduSorgulamaServices.Servis5001Request S5001R = new TOBBHesKoduSorgulamaServices.Servis5001Request();
S5001R.Kodu = Kodu;
S5001R.Sifre = Sifre;
S5001R.HesKodu = HesKodu;
TOBBHesKoduSorgulamaServices.Servis5001Response S5001Response = ?
Which One Is Right For Me?
Waiting for your support, good work ...

Unexpected XML declaration. The XML declaration must be the first node in the document

I am trying to get my xml response in the correct format using HttpUtility.Decode. Upon doing and loading it in Xml Document, it is throwing the following exception : Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it. Line 1, position 313. I'm not sure why because the xml declaration does appear as the first node if I'm not mistaken. Im fairly new to XML so any help will be appreciated. How do I fix this? Thanks.
XML decode response:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><Query_With_StringResponse xmlns="http://www.syspro.com/ns/query/"><Query_With_StringResult><?xml version="1.0" encoding="Windows-1252"?>
<ARListOfCustomers Language='05' Language2='EN' CssStyle='' DecFormat='1' DateFormat='01' Role='01' Version='7.0.005' OperatorPrimaryRole=' ' >
<QueryOptions>
<ReportSequence>CU</ReportSequence>
<PriceCode/>
<PriceProductmatrix>N</PriceProductmatrix>
<ExtraFields>N</ExtraFields>
<InterestExemptionStatusSelection>A</InterestExemptionStatusSelection>
<TaxExemptionSelection>A</TaxExemptionSelection>
<CustomerSelectionFilterType>A</CustomerSelectionFilterType>
<CustomerSelectionFilterValue/>
<CustomerClassSelectionFilterType>A</CustomerClassSelectionFilterType>
<CustomerClassSelectionFilterValue/>
<GeographicAreaSelectionFilterType>A</GeographicAreaSelectionFilterType>
<GeographicAreaSelectionFilterValue/>
<BranchSelectionFilterType>A</BranchSelectionFilterType>
<BranchSelectionFilterValue/>
<SalespersonSelectionFilterType>A</SalespersonSelectionFilterType>
<SalespersonSelectionFilterValue/>
<LineDiscountCodeSelectionFilterType>A</LineDiscountCodeSelectionFilterType>
<LineDiscountCodeSelectionFilterValue/>
<TermsSelectionFilterType>A</TermsSelectionFilterType>
<TermsSelectionFilterValue/>
<ProductCategorySelectionFilterType>A</ProductCategorySelectionFilterType>
<ProductCategorySelectionFilterValue/>
<InvoiceDiscountCodeSelectionFilterType>A</InvoiceDiscountCodeSelectionFilterType>
<InvoiceDiscountCodeSelectionFilterValue/>
<CurrencySelectionFilterType>A</CurrencySelectionFilterType>
<CurrencySelectionFilterValue/>
<CreditLimitSelectionFilterType>A</CreditLimitSelectionFilterType>
<CreditLimitSelectionFilterValue/>
</QueryOptions>
<Customer>
<CustomerListHeader>
<Customer>TSAR</Customer>
<CustomerName>TSAR BUSINESS SOLUTION</CustomerName>
<CustomerShortName>TSAR BUSINESS SOLUTI</CustomerShortName>
<Branch>TSAR</Branch>
<BranchDescription>HEAD OFFICE TSAR</BranchDescription>
<Geography>031</Geography>
<GeographyDescription>DURBAN</GeographyDescription>
<Class/>
<ClassDescription>** Not on file **</ClassDescription>
<BalanceType>Op-item</BalanceType>
<Sales>IVAN</Sales>
<CreditLimit> 0</CreditLimit>
<Currency>R</Currency>
<CurrencyDescription>Rand</CurrencyDescription>
<Telephone/>
<InvoiceTermsCode>CO</InvoiceTermsCode>
<TermsCodeDescription>CASH ON DELIVERY</TermsCodeDescription>
</CustomerListHeader>
<CustomerListDetails>
<Contact/>
<TaxNo>Tax No:</TaxNo>
<SpecialInstructions/>
<SoldToAddress1/>
<SoldToAddress2/>
<SoldToAddress3/>
<SoldToAddress3Loc/>
<SoldToAddress4/>
<SoldToAddress5/>
<SoldToAddress6/>
<SoldToGpsLat> 0.000000</SoldToGpsLat>
<SoldToGpsLong> 0.000000</SoldToGpsLong>
<ShipToAddress1>STRAUSS DALY</ShipToAddress1>
<ShipToAddress2>41 RICHFONT CRICLE</ShipToAddress2>
<ShipToAddress3>DURBAN</ShipToAddress3>
<ShipToAddress3Loc/>
<ShipToAddress4>KZB</ShipToAddress4>
<ShipToAddress5>SOUTH AFRICA</ShipToAddress5>
<ShipToAddress6>4000</ShipToAddress6>
<ShipToGpsLat> 0.000000</ShipToGpsLat>
<ShipToGpsLong> 0.000000</ShipToGpsLong>
<GSTNumber/>
<LineDiscCode/>
<InvDiscCode/>
<DefaultPriceCode/>
<CompanyTaxNumber/>
<ExemptFinChg>No finance charges</ExemptFinChg>
</CustomerListDetails>
</Customer>
<ReportSummary>
<NoOfCustomersListed> 1</NoOfCustomersListed>
</ReportSummary>
</ARListOfCustomers>
</Query_With_StringResult></Query_With_StringResponse></soap:Body></soap:Envelope>
My code: Code breaks on "doc.LoadXml(decodedXml);"
public async Task<string> CreateSoapEnvelop()
{
string soapString = #"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"" xmlns:xsd=""http://www.w3.org/2001/XMLSchema"" xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/"">
<soap:Body>
<Query_With_String xmlns=""http://www.syspro.com/ns/query/"">
<UserId>" + Settings.GUID + #"</UserId>
<BusinessObject></BusinessObject>
<XMLIn></XMLIn>
</Query_With_String>
</soap:Body>
</soap:Envelope>";
try
{
HttpResponseMessage response = await PostXmlRequest("http://sysprowebservices/query.asmx", soapString);
var soapResponse = await response.Content.ReadAsStringAsync();
var decodedXml = HttpUtility.HtmlDecode(soapResponse);
XmlDocument doc = new XmlDocument();
doc.LoadXml(decodedXml);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
nsmgr.AddNamespace("ab", "http://www.syspro.com/ns/query/");
nsmgr.AddNamespace("bg", " https://bixg.choicepoint.com/webservices/3.0");
nsmgr.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
XmlNode xmlnode = doc.DocumentElement.SelectSingleNode("/soap:Envelope/soap:Body/ab:Query_With_StringResponse/ab:Query_With_StringResult", nsmgr);
string customer = xmlnode.SelectSingleNode("CustomerName").InnerText;
}
catch (Exception ex)
{
string msg = ex.Message;
}
return "";
}
public static async Task<HttpResponseMessage> PostXmlRequest(string baseUrl, string xmlString)
{
using (var httpClient = new HttpClient())
{
var httpContent = new StringContent(xmlString, Encoding.UTF8, "text/xml");
httpContent.Headers.Add("SOAPAction", "http://www.syspro.com/ns/query/Query_With_String");
return await httpClient.PostAsync(baseUrl, httpContent);
}
}
UPDATE
{
HttpResponseMessage response = await PostXmlRequest("http://196.37.159.30/sysprowebservices/query.asmx", soapString);
var soapResponse = await response.Content.ReadAsStringAsync();
XmlDocument doc = new XmlDocument();
doc.LoadXml(soapResponse);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
nsmgr.AddNamespace("ab", "http://www.syspro.com/ns/query/");
nsmgr.AddNamespace("bg", " https://bixg.choicepoint.com/webservices/3.0");
nsmgr.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
XmlNode xmlnode = doc.DocumentElement.SelectSingleNode("/soap:Envelope/soap:Body/ab:Query_With_StringResponse/ab:Query_With_StringResult", nsmgr);
var xmlDecoded = HttpUtility.HtmlDecode(xmlnode.ToString());
}
Update Response from XmlDecode: "System.Xml.XmlElement"
First of all, don't roll your own SOAP client unless you know very well what you're doing. Can't you use WCF instead?
But you have a SOAP call that returns ... XML. You can't just decode the entire response as if it were HTML, because then the encoding of the inner XML will be lost, resulting in an invalid XML document.
You need to read the repsonse first, then obtain the inner XML string and then decode that:
XmlDocument doc = new XmlDocument();
doc.LoadXml(soapResponse);
XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("soap", "http://schemas.xmlsoap.org/soap/envelope/");
nsmgr.AddNamespace("ab", "http://www.syspro.com/ns/query/");
nsmgr.AddNamespace("bg", " https://bixg.choicepoint.com/webservices/3.0");
nsmgr.AddNamespace("xsd", "http://www.w3.org/2001/XMLSchema");
nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
XmlNode xmlnode = doc.DocumentElement.SelectSingleNode("/soap:Envelope/soap:Body/ab:Query_With_StringResponse/ab:Query_With_StringResult", nsmgr);
Now xmlnode holds the encoded XML. Decode that and do whatever you want with it:
var decodedXml = HttpUtility.HtmlDecode(xmlnode.InnerXml);

C# xmlserialization SoapEnvelope namespace formating

Im having issues building a soapenvelope in c#. Here is an example of desired field in output
<xml version="1.0">
<Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="id1">
<Body d2p1:type="Body" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance">
<test xmlns:q1="http://www.w3.org/2001/XMLSchema" d2p1:type="q1:string">hello
</test>
</Body>
</Envelope>
However when I serialize the class i get this
<xml version="1.0">
<Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" id="id1">
<test href="#id2" />
</Envelope>
<Body id="id2" d2p1:type="Body" xmlns:d2p1="http://www.w3.org/2001/XMLSchema-instance">
<test xmlns:q1="http://www.w3.org/2001/XMLSchema" d2p1:type="q1:string">hello
</test>
</Body>
As you can see the body is outside the envelope.
Here is the class
namespace soaptest
{
public class Envelope
{
public Body test;
}
public class Body
{
public string test;
}
}
And here is how Im serializing
Envelope test = new Envelope();
MemoryStream ms = new MemoryStream();
test.test = new soaptest.Body();
test.test.test = "hello";
XmlWriter writer = new XmlTextWriter(ms, Encoding.UTF8);
SoapReflectionImporter importer = new SoapReflectionImporter();
XmlTypeMapping map = importer.ImportTypeMapping(typeof(Envelope));
XmlSerializer serializer = new XmlSerializer(map);
writer.WriteStartElement("xml version=\"1.0\"");
serializer.Serialize(writer, test);
ms.Position = 0;
StreamReader sr = new StreamReader(ms);
string output = sr.ReadToEnd();
Now I can do away with all attributes atm. I just need it to be
<?xml version="1.0"?>
<Envelope>
<Body>
//body elements
</Body>
</Envelope>
So how can I get the serializer to do this? Or is there a good SoapEnvelope Library for .net?
Why so complex?
Model:
public class Envelope
{
public Body Body;
}
public class Body
{
[XmlElement("test")]
public string Test;
}
Usage:
Envelope envelope = new Envelope();
envelope.Body = new Body();
envelope.Body.Test = "hello";
XmlSerializer serializer = new XmlSerializer(typeof(Envelope));
serializer.Serialize(Console.Out, envelope);
Result:
<?xml version="1.0" encoding="cp866"?>
<Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Body>
<test>hello</test>
</Body>
</Envelope>

My XSLT not working

Very new to XSLT and need help with an XSLT transformation that I can't get working. The problem I'm having is the transformed document coming out with a blank CONO and CUNO elements.
I've been using http://www.w3schools.com/xsl/xsl_value_of.asp as a guide but it doesn't seem to be working.
Here's the original XML.
<?xml version="1.0" encoding="utf-8"?>
<GetBasicData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="CRS610MI">
<CONO xmlns="">1</CONO>
<CUNO xmlns="">123456</CUNO>
</GetBasicData>
Here's my XSLT
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"><xsl:output method="xml"/>
<xsl:template match="/">
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<GetBasicData xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="CRS610MI">
<CONO xmlns="">
<xsl:value-of select="GetBasicData/CONO"/>
</CONO>
<CUNO xmlns="">
<xsl:value-of select="GetBasicData/CUNO"/>
</CUNO>
</GetBasicData>
</soap:Body>
</soap:Envelope>
</xsl:template>
</xsl:stylesheet>
Here's the C# code I'm using for the transformation
private static Boolean TransformXML(XPathDocument xPathDocument, String xslPath, out XmlDocument xmlDocument)
{
try
{
using (MemoryStream memoryStream = new MemoryStream())
{
using (StreamWriter streamWriter = new StreamWriter(memoryStream))
{
XmlWriter xmlWriter = XmlWriter.Create(streamWriter);
XsltSettings xsltSettings = new XsltSettings();
xsltSettings.EnableScript = true;
XslCompiledTransform xslCompiledTransform = new XslCompiledTransform();
xslCompiledTransform.Load(xslPath, xsltSettings, null);
xslCompiledTransform.Transform(xPathDocument, xmlWriter);
memoryStream.Position = 0;
StreamReader streamReader = new StreamReader(memoryStream);
XmlReader xmlReader = XmlReader.Create(streamReader);
xmlDocument = new XmlDocument();
xmlDocument.Load(xmlReader);
}
}
}
catch (Exception exception)
{
Debug.WriteLine(exception);
xmlDocument = null;
return false;
}
return true;
}
In your input XML, the GetBasicData element has a_default namespace_ (which happens to be "CRS610MI"). On the other hand, the CONO and CUNO element do not have a namespace.
Add a namespace declaration to your stylesheet. Also, the output option indent="yes" makes the output more human-readable.
It appears that your intent is to put the input XML inside soap:Body without changing the content. In this case, you do not have to redefine everything in an XSLT stylesheet - copy as much as possible from the original XML.
Stylesheet
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:crs="CRS610MI" exclude-result-prefixes="crs">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="/">
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<xsl:apply-templates select="node()|#*"/>
</soap:Body>
</soap:Envelope>
</xsl:template>
<xsl:template match="node()|#*">
<xsl:copy>
<xsl:apply-templates select="node()|#*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Output
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" soap:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<soap:Body>
<GetBasicData xmlns="CRS610MI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CONO xmlns="">1</CONO>
<CUNO xmlns="">123456</CUNO>
</GetBasicData>
</soap:Body>
</soap:Envelope>

WCF Method is returning xml fragment but no xml UTF-8 header

My method does not return the header, just the root element xml.
internal Message CreateReturnMessage(string output, string contentType)
{
// create dictionaryReader for the Message
byte[] resultBytes = Encoding.UTF8.GetBytes(output);
XmlDictionaryReader xdr = XmlDictionaryReader.CreateTextReader(resultBytes, 0, resultBytes.Length, Encoding.UTF8, XmlDictionaryReaderQuotas.Max, null);
if (WebOperationContext.Current != null)
WebOperationContext.Current.OutgoingResponse.ContentType = contentType;
// create Message
return Message.CreateMessage(MessageVersion.None, "", xdr);
}
However, the output I get is:
<Test>
<Message>Hello World!</Message>
</Test>
I would like the output to render as:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Test>
<Message>Hello World!</Message>
</Test>
Have a look at this URL http://blogs.msdn.com/b/wifry/archive/2007/05/15/wcf-bodywriter-and-raw-xml-problems.aspx
Pass the xml string to the custom bodywriter and it will output xml declaration
so assuming output param is coming in as...
<Test>
<Message>Hello World!</Message>
</Test>
What do you expect to happen? You aren't writing xml, just reading the output string through a reader. The reader class won't add anything to your fragment, it's a reader, not a writer.
You could so something like this instead...It will parse your output as xml and then you can add a declaration before giving it to the message.
var output = "<Test><Message>Hello World!</Message></Test>";
var xd = XDocument.Parse(output);
xd.Declaration = new XDeclaration("1.0", "utf-8", "yes");
return Message.CreateMessage(version, messageFault, xd.ToString());

Categories

Resources