First time using serialization in XNA so forgive me if I'm over looking soemthing obvious.
Basically, in my game, I have two objects, Square (storing data about each square in the game) and one called Enemy (storing information and behaviours about the enemey).
I want to serialize this data so I can save and load it in at a later date.
I've put them both into a single object called Data and serialised that.
However the xml data reads like so:
<?xml version="1.0" encoding="utf-8"?>
<Data xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<squares>
<Square />
<Square />
<Square />
<Square />
<Square />
<Square />
<Square />
<Square />
<Square />
etc
My code:
Data.cs
public class Data
{
public Square[] squares;
public Enemy[] enemies;
public Data()
{
}
}
SaveFucntion:
Data data = new Data();
data.squares = squares;
data.enemies = enemies;
StreamWriter file2 = new StreamWriter(Content.RootDirectory + "\\xml.txt");
XmlSerializer x = new XmlSerializer(typeof(Data));
x.Serialize(file2, data);
What am I doing wrong? or what would be the best way to achieve this?
Related
Our tack is c# .net 4.7 logging through NLog library to a "Graylog" GELF input which of course is storing them in an elasticsearch cluster.
The application utilizes logging heavily, but EVERYTHING is sent through as strings - no matter if it was something other than a string in code.
I want to be able send my custom logger properties as their true data types so that I can aggregate on my statistical number fields.
I DO NOT want to constrain my developers and do this with scripted fields, or pre-mapping an index in elasticsearch - in fact, graylog manages my index for me. Nor do I want to utilize graylog pipeline processor - my poor graylog does enough work. I want them to be able to send stat data as their real data types and have them mapped as "long" or "number".
A code snippet from my stuff:
public void InfoExtended2(String Message, Dictionary<string, int> extrafields, [CallerMemberName] string callerMethodName = "", [CallerFilePath] string callerFilePath = "", [CallerLineNumber] int sourceLineNumber = 0)
{
var fileName = callerFilePath.Substring(callerFilePath.LastIndexOf(#"\") + 1).Replace(".cs", "");
var caller = $"{fileName}.{callerMethodName}()Line:{sourceLineNumber}";
var logger = LogManager.GetLogger(caller);
if (!(extrafields.Count == 0))
{
foreach (var field in extrafields)
{
string mykey = field.Key.ToString();
extrafields.TryGetValue(field.Key, out int myvalue);
//be careful whats in object!
if (!logger.Properties.ContainsKey(mykey)) { logger.Properties.Add(mykey, "{#myvalue}"); } else { logger.Properties[mykey] = "{#myvalue}"; }
}
}
logger.Info()
.Message(Message)
.Property("ComeOnNow3", 87)
.Write();
// Create the LogEventInfo object
//LogEventInfo logEvent = new LogEventInfo();
// Now add the event characteristics
//logEvent.Properties["EventCode"] = 2222;
//logEvent.Level = NLog.LogLevel.Info;
//logEvent.Properties["EventCode]."]
//logEvent.Message = "My Message";
////logEvent.Exception = ex;
//logger.Log(logEvent);
//logger.Info("{#Message}", new Dictionary<string, int> { { "key1", 1 }, { "key2", 2 } }); // dict. Result: Test "key1"=1, "key2"=2
}
I've tried a few different ways there with no luck.
If I make a POST GELF call myself with JSON fields representing ints instead of strings, it works. My field is brand new to the index and when I go check the mapping it comes back as a long. I want my code to do that.
Test GELF Call:
{
"version": "1.1",
"host": "example.org",
"short_message": "A short message that helps you identify what is going on",
"full_message": "Backtrace here\n\nmore stuff",
"timestamp": 1385053862.3072,
"level": 1,
"_user_id": 9001,
"_some_info": "foo",
"_some_env_var": "bar"
}
Resulting mapping for user id:
"user_id" : {
"type" : "long"
What our nlog target currently looks like:
<targets>
<target name="gelftcp"
type="gelftcp"
facility="Custom Facility"
remoteaddress="192.168.95.15"
remoteport="12201"
layout="${longdate}${newline}type: ${level:uppercase=true}${newline}class: ${logger}${newline}stacktrace: ${stacktrace}${newline}error message: ${message}${newline}exception: ${exception:format=tostring,data:maxinnerexceptionlevel=10}">
<parameter name="logged_at" layout="${longdate}" />
<parameter name="type" layout="${level:uppercase=true}" />
<parameter name="class" layout="${logger}" />
<parameter name="CustomInt" layout="${event-properties:item=CustomInt}" as="number" />
<parameter name="stacktrace" layout="${stacktrace}" />
<parameter name="error_message" layout="${message}" />
<parameter name="ComeOnNow3" layout="${event-properties:item=ComeOnNow3} " />
<parameter name="exception" layout="${exception:format=tostring,data:maxinnerexceptionlevel=10}" />
<attribute name="eventProperties" encode="false" >
<layout type='JsonLayout' includeAllProperties="true" maxRecursionLimit="2"/>
</attribute>
<variable name="ComeOnNow2" value ="${event-context:ComeOnNow2}" />
</target>
Take it easy on me, I'm not the original author of this code. Just someone tasked with picking up slack & deploying in its current state.
UPDATE:
Tried the first suggestion. Even added the field I'm testing:
<field name="ComeOnNow3" layout="${threadid}" type="System.Int32" />
Attempted this log entry:
logger.Info()
.Message(Message)
.Property("ComeOnNow3", 87)
.Write();
My mapping still comes back as "keyword".
SOLVED:
The trick was to switch to Http instead of Tcp.
Instead of using "gelftcp". Then you can try out GelfLayout instead:
https://www.nuget.org/packages/NLog.GelfLayout
You can combine it with the TCP network-target:
<nlog>
<extensions>
<add assembly="NLog.Layouts.GelfLayout" />
</extensions>
<targets async="true">
<target type="Network" name="gelftcp" address="tcp://192.168.95.15:12201" newLine="true" lineEnding="Null">
<layout type="GelfLayout" facility="MyFacility">
<field name="threadid" layout="${threadid}" type="System.Int32" />
</layout>
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="gelftcp" />
</rules>
</nlog>
It also has some automatic conversion logic for simple NLog LogEventInfo.Properties (Decimal + Double + Integer + Boolean)
More examples can be found here: https://github.com/farzadpanahi/NLog.GelfLayout
In Log Apps, I have a Source.xml file, which is required to be transformed into another destination.xml using XSLT.
Within XSLT, I need to implement some custom logic using C# code which will be uploaded to Azure Integration Account "Assemblies Section"
I have created one C# assembly file with StrongName but need to understand how the methods of C# assembly can be called from XSLT.
Would appreciate if anyone can share a working sample code with a very basic example.
I found an example for your reference:
The c# code show as below:
using System;
namespace ExtAssembly
{
public static class CalcFunctions
{
public static Int64 Add(Int64 a, Int64 b)
{
return a + b;
}
public static Int64 Subtract(Int64 a, Int64 b)
{
return a - b;
}
public static Int64 Multiply(Int64 a, Int64 b)
{
return a * b;
}
public static Double Divide(Int64 a, Int64 b)
{
return a / b;
}
}
}
And we can use the c# code in xslt as below:
<?xml version="1.0" encoding="UTF-16"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform Jump " xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl userCSharp" version="1.0" xmlns:userCSharp="http://schemas.microsoft.com/BizTalk/2003/userCSharp Jump ">
<xsl:output omit-xml-declaration="yes" media-type="application/text" method="text" version="1.0" />
<xsl:param name="MethodName" />
<xsl:param name="Parameters" />
<xsl:template match="/">
<xsl:value-of select ="userCSharp:Invoke($MethodName, substring-before(substring-after($Parameters, '('), ')'))" />
</xsl:template>
<msxsl:script language="C#" implements-prefix="userCSharp">
<msxsl:assembly name="ExtAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx" />
<msxsl:using namespace="System.Reflection" />
<msxsl:using namespace="System.Text.RegularExpressions" />
<msxsl:using namespace="ExtAssembly" />
<![CDATA[
public object Invoke(string methodName, string methodParameters)
{
MatchCollection matches = new Regex("((?<=\")[^\"]*(?=\"(,|$)+)|(?<=,|^)[^,\"]*(?=,|$))").Matches(methodParameters);
ParameterInfo[] pars = typeof(CalcFunctions).GetMethod(methodName).GetParameters();
object[] methodPars = new object[pars.Length];
for (int i = 0; i < pars.Length; i++)
{
methodPars[i] = Convert.ChangeType(matches[i].Value, pars[i].ParameterType);
}
return typeof(CalcFunctions).GetMethod(methodName).Invoke(null, methodPars);
}
]]>
</msxsl:script>
</xsl:stylesheet>
After that, we can call it in our logic app(provide it wih "MethodName" and "Parameters" in "Transform xml" action).
For further information, you can refer to this example.
Hope it would be helpful to your problem.
Question is about how to use c# assembly with XSLT.
Both XSLT AND C# are being placed inside Azure Integration Account i.e in Maps and Assembly artifact sections respectively
I would like to create a dictionary and populate it in the configuration file for Unity like shown here. However, that example seems to be from an older version of Unity IoC but I would like to know how to do this with Unity 4.
<type ... to="MyTypeServer">
<typeConfig>
<property Name="Converters" KeyType"string" ValueType="IConverter">
<entry>
<key>csv</key>
<value><dependency name="csvConverter"/></value>
</entry>
<entry>
<key>xml</key>
<value><dependency name="xmlConverter"/></value>
</entry>
</property>
</typeConfig>
</type>
<type name="csvConverter" from="IConverter" to="MyCsvConverter">
</type>
<type name="xmlConverter" from="IConverter" to="MyXmlConverter">
</type>
And here is the class:
public class MyTypeServer
{
public IDictionary<string, IConverter> Converters
{
set;
private get;
}
public void DoConversion(string fileName)
{
string fileType = Path.GetFileExtension(fileName);
IConverter converter = Converters[fileType];
if (converter != null)
converter.DoConversion(fileName);
..
...
}
}
I have been trying for hours and researching but no luck.
From the codeplex link you posted:
This is a quick pseudo code of the type of stuff we can have with dictionary.
To me, this reads "we could do something like this if we implemented the feature". Aligns with my experience with unity, I've never come across something like this.
What you can do however: register all the converters, have them all injected as array and then build the dictionary yourself.
// register in code or in xml...
container.RegisterType<IConverter, XmlConverter>( "xml-Converter" );
container.RegisterType<IConverter, JsonConverter>( "json-Converter" );
internal class ConverterConsumer
{
public ConverterConsumer( IConverter[] converters )
{
_converters = converters.ToDictionary( x => x.FileType, x => x );
}
#region private
private Dictionary<string, IConverter> _converters;
#endregion
}
public interface IConverter
{
string FileType { get; }
void DoConversion( string fileName );
}
Posting as an answer because I do not have sufficient points to comment. This is what I did to solve my problem. Not exactly a Dictionary approach but it might help.
My requirements - Store app settings in the Unity XML file as opposed to app.config
I had various objects which were registered in the Unity XML and they had properties like connection strings, Azure queue names , Azure blob container names, etc. I found myself duplicating these values in the XML very often. I could make my objects read values from *appSettings** element of app.config or some other configuration section. However, I chose not to use the app.config for the sake of keeping my objects more testable.
My solution - Use the <instance> element to register reusable string values
I registered all reusable connection strings in a single location as shown below and without any duplications:
<instance name="cnstring1" value="blah connection string 1"></instance>
<instance name="cnstring2" value="blah connection string 2"></instance>
<instance name="azurequeue1" value="name of receiver queue "></instance>
<instance name="azurequeue2" value="name of sender queue "></instance>
<instance name="azurestoragecnstring" value="your azure storage account connection string 0001"></instance>
Reference the name-value pairs using the dependency element whereever required.
Example XML:
<register name="i2" mapTo="someimplementation" type="someinterface">
<property name="Database">
<dependency name="cnstring1" />
</property>
</register>
Example C# code snippet:
public string Database { get; set; }
At run time the property Database of the object with the registration i2 will be set to the value of blah connection string 1
Caveats
Storing connection strings in plain text XML might not be safe especially if the connection string has username and password values.
I want to import this XML file into C#.
<?xml version="1.0" encoding="UTF-8"?>
<YamahaAmplifier>
<Root>
<RootName>SYS</RootName>
<UseRoot>YES</UseRoot>
<Device>
<DeviceName>MODELNAME</DeviceName>
<UseFunction>YES</UseFunction>
<GETCMD>#SYS:MODELNAME=?</GETCMD>
<Parameter>
<Number>1</Number>
<Type>SINGLEVAL</Type>
<Name>Character Code: Ascii, Variable Length (1 to 16 characters)</Name>
</Parameter>
</Device>
<Device>
<DeviceName>SPPATTERN1AMP</DeviceName>
<UseFunction>YES</UseFunction>
<PUTCMD>#SYS:SPPATTERN1AMP=</PUTCMD>
<GETCMD>#SYS:SPPATTERN1AMP=?</GETCMD>
<Parameter>
<Number>1</Number>
<Type>SINGLEVAL</Type>
<Name>7ch Normal</Name>
</Parameter>
<Parameter>
<Number>2</Number>
<Type>SINGLEVAL</Type>
<Name>7ch +1ZONE</Name>
</Parameter>
<Parameter>
<Number>3</Number>
<Type>SINGLEVAL</Type>
<Name>7ch +2ZONE</Name>
</Parameter>
<Parameter>
<Number>4</Number>
<Type>SINGLEVAL</Type>
<Name>7ch +FRONT</Name>
</Parameter>
<Parameter>
<Number>5</Number>
<Type>SINGLEVAL</Type>
<Name>7ch +FPR</Name>
</Parameter>
</Device>
</Root>
<Root>
<RootName>SYS2</RootName>
<UseRoot>YES</UseRoot>
<Device>
<DeviceName>MODELNAME2</DeviceName>
<UseFunction>YES</UseFunction>
<GETCMD>#SYS:MODELNAME=?</GETCMD>
<Parameter>
<Number>1</Number>
<Type>SINGLEVAL</Type>
<Name>Character Code: Ascii, Variable Length (1 to 16 characters)</Name>
</Parameter>
</Device>
<Device>
<DeviceName>SPPATTERN1AMP2</DeviceName>
<UseFunction>YES</UseFunction>
<PUTCMD>#SYS:SPPATTERN1AMP=</PUTCMD>
<GETCMD>#SYS:SPPATTERN1AMP=?</GETCMD>
<Parameter>
<Number>1</Number>
<Type>SINGLEVAL</Type>
<Name>7ch Normal</Name>
</Parameter>
<Parameter>
<Number>2</Number>
<Type>SINGLEVAL</Type>
<Name>7ch +1ZONE</Name>
</Parameter>
<Parameter>
<Number>3</Number>
<Type>SINGLEVAL</Type>
<Name>7ch +2ZONE</Name>
</Parameter>
</Device>
</Root>
</YamahaAmplifier>
I have created these classes to carry it:
[Serializable, XmlRoot("YamahaAmplifier")]
public class YamahaAmplifier
{
[XmlArray(ElementName = "Root")]
public List<Root> Roots = new List<Root>();
}
[Serializable()]
public class Root
{
[XmlElement("RootName")]
public string RootName;
[XmlElement("UseRoot")]
public string UseRoot;
[XmlArray("Device")]
public List<Device> Devices = new List<Device>();
}
[Serializable()]
public class Device
{
[XmlElement("DeviceName")]
public string DeviceName;
[XmlElement("UseFunction")]
public string UseFunction;
[XmlElement("GETCMD")]
public string GETCMD;
[XmlElement("PUTCMD")]
public string PUTCMD;
[XmlArray("Parameter")]
public List<Parameter> Parameters = new List<Parameter>();
}
[Serializable()]
public class Parameter
{
[XmlElement("Number")]
public int Number;
[XmlElement("Type")]
public string Type;
[XmlElement("Name")]
public string Name;
}
And then this code to import to C#:
try
{
using (FileStream reader = new FileStream("C:\\Civview\\YNCA_Command_List_RX-A3000_U.xml", FileMode.Open))
{
XmlSerializer ser = new XmlSerializer(typeof(YamahaAmplifier));
o = ser.Deserialize(reader) as YamahaAmplifier;
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
But I get an error and I just cant get around it, have have been testing a number of solutions to get it to work without sucess.
The error I get is:
System.InvalidOperationException: There is an Error in XML document (2, 2). ---> System-MethodAcessException: Attempt by method ´Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderYamahaAmplifier.Read5_YamahaAmplifier(Boolean, Boolean)´ to access method ´HSPI_YAMAHA_RECEIVER.Util+YamahaAmplifier..ctor() failed.
at Microsoft.Xml.Serialization.GeneratedAssembly.XmlSerializationReaderYamahaAmplifier.Read5_YamahaAmplifier(Booleanb isNullable, Boolean checkType)
Any suggestions? A better way of doing it? Anything?
Ok, so now I have imported a nice and neat structure of information that I want to use. One part of my program uses all the information in the structure to create a user interface. Another part of the program must decide what to do if one of the buttons are pressed or the sliers are changed. This latter part gets three pieces of information automatically, I cannot change the code that does this. The information I get is the "RootName", "DeviceName" and "Number" under "Parameter" class.
So what I need to do is to search for the matchin RootName, and under that the matching DeviceName and take that DeviceNames string in "PUTCMD" and add the parameter name which corresponds to the Number I get.
Is there a smart way of doing this? Finding the correct Device under the correct Root and then take the data out of that to creat my transmission string.
Greatful for any help in the correct direction.
Thanks, your fix works if I create a new project and just enter the code I posted with your changes. But it does not work in my original program. I will have to continue collecting information to describe the problem.
Copy pasting it back from the test program made it work with one exception. I had done a misstake in the testprogram typing something like roots.Roots[1].Devices.Count() and that worked there. But when copying back to the original program, I had to remove the () since its not a method.
This is my response structure that i am getting
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetPrice_HotelResponse xmlns="PricingAirAPI">
<GetPrice_HotelResult xmlns:a="PricingHotelAPI" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:Error i:nil="true" />
<a:Results xmlns:b="PricingCommonAPI">
<b:HotelSearchResult>
<b:AmountAfterTax>561.9600</b:AmountAfterTax>
<b:AmountBeforeTax>561.9600</b:AmountBeforeTax>
<b:B2B2BHotelPrice xmlns:c="http://schemas.datacontract.org/2004/07/HotelB2B2BPricingEngine">
<c:AgentMarkUp>0</c:AgentMarkUp>
<c:SubAgentMarkUp>0</c:SubAgentMarkUp>
</b:B2B2BHotelPrice>
<b:BookingSource>JacTravel</b:BookingSource>
<b:CityId i:nil="true" />
<b:CityName i:nil="true" />
<b:CountryCode i:nil="true" />
<b:Currency>GBP</b:Currency>
<b:Discount>0.00</b:Discount>
<b:HotelCode>12035</b:HotelCode>
<b:HotelName i:nil="true" />
<b:HotelSupplierResultType>None</b:HotelSupplierResultType>
<b:IsUniversalApiResult>true</b:IsUniversalApiResult>
<b:Price xmlns:c="http://schemas.datacontract.org/2004/07/TekTravel.Hotel.PricingEngine">
<b:AccPriceType>NetFare</b:AccPriceType>
<b:AdditionalTxnFee>0.0</b:AdditionalTxnFee>
<b:AgentCommission>0</b:AgentCommission>
<b:AgentCommissionRate>0</b:AgentCommissionRate>
<b:AgentIncentiveAmt>0.00</b:AgentIncentiveAmt>
<b:AgentIncentiveRate>0.00</b:AgentIncentiveRate>
<b:AgentMarkUp>0</b:AgentMarkUp>
<b:AgentMarkUpAmt>0.0000</b:AgentMarkUpAmt>
<b:AgentMarkUpType>Percentage</b:AgentMarkUpType>
<b:AgentPLB>0</b:AgentPLB>
<b:AgentPLBRate>0</b:AgentPLBRate>
<b:AirlineBaggageCharges>0</b:AirlineBaggageCharges>
<b:AirlineMealCharges>0</b:AirlineMealCharges>
<b:AirlineSeatCharges>0</b:AirlineSeatCharges>
<b:AirlineTransFee>0</b:AirlineTransFee>
<b:CateringCharge>0</b:CateringCharge>
<b:CessTax>0</b:CessTax>
<b:ChargeBU />
<b:CommissionType>RB</b:CommissionType>
<b:ConvenienceCharges>0</b:ConvenienceCharges>
<b:Currency />
<b:CurrencyCode>INR</b:CurrencyCode>
<b:DealId>0</b:DealId>
<b:Discount>0</b:Discount>
<b:EduCessAmount>0</b:EduCessAmount>
<b:EduCessRate>0</b:EduCessRate>
<b:FareBreakdown i:nil="true" />
<b:IsGPEnabled>false</b:IsGPEnabled>
<b:IsOurServiceTaxOnBaseFarePlusYQ>false</b:IsOurServiceTaxOnBaseFarePlusYQ>
<b:IsOurServiceTaxOnComm>false</b:IsOurServiceTaxOnComm>
<b:IsServiceChargeApplicable>true</b:IsServiceChargeApplicable>
<b:IsServiceTaxOnBaseFarePlusYQ>false</b:IsServiceTaxOnBaseFarePlusYQ>
<b:Markup>80</b:Markup>
<b:NetFare>0</b:NetFare>
<b:OtherCharge>0</b:OtherCharge>
<b:OurCommRate>0</b:OurCommRate>
<b:OurCommission>0</b:OurCommission>
<b:OurCommissionType>RB</b:OurCommissionType>
<b:OurEduCessAmt>0</b:OurEduCessAmt>
<b:OurEduCessRate>0</b:OurEduCessRate>
<b:OurIncentiveAmt>0</b:OurIncentiveAmt>
<b:OurIncentiveRate>0</b:OurIncentiveRate>
<b:OurPLB>0</b:OurPLB>
<b:OurPLBRate>0</b:OurPLBRate>
<b:OurPlbType i:nil="true" />
<b:OurServiceTaxAmt>0</b:OurServiceTaxAmt>
<b:OurServiceTaxRate>0</b:OurServiceTaxRate>
<b:OurTdsCommAmt>0</b:OurTdsCommAmt>
<b:OurTdsIncentiveAmt>0.0</b:OurTdsIncentiveAmt>
<b:OurTdsPLBAmt>0</b:OurTdsPLBAmt>
<b:OurTdsRate>0</b:OurTdsRate>
<b:PlbType i:nil="true" />
<b:PrfCurrency i:nil="true" />
<b:PrfROE>0.0</b:PrfROE>
<b:PriceId>0</b:PriceId>
<b:PublishedFare>0</b:PublishedFare>
<b:RateOfExchange>1</b:RateOfExchange>
<b:ResultId>0</b:ResultId>
<b:ReverseHandlingCharge>0</b:ReverseHandlingCharge>
<b:SegmentFee>0</b:SegmentFee>
<b:ServiceTaxRate>0</b:ServiceTaxRate>
<b:SeviceTax>0</b:SeviceTax>
<b:StockType />
<b:SupplierId>0</b:SupplierId>
<b:TDSPLB>0</b:TDSPLB>
<b:Tax>0</b:Tax>
<b:TaxBreakup i:nil="true" xmlns:d="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
<b:TdsCommission>0</b:TdsCommission>
<b:TdsIncentive>0.00</b:TdsIncentive>
<b:TdsRate>0</b:TdsRate>
<b:TotalGP>0</b:TotalGP>
<b:TransactionFee>0</b:TransactionFee>
<b:WLCharge>0</b:WLCharge>
<b:WLPrice i:nil="true" />
<b:WhiteLabelDiscount>0</b:WhiteLabelDiscount>
<b:YQTax>0</b:YQTax>
<c:DynamicPriceAgentComm>0</c:DynamicPriceAgentComm>
<c:DynamicPriceOurComm>0</c:DynamicPriceOurComm>
</b:Price>
<b:RateType>Negotiated</b:RateType>
<b:RoomDetails />
<b:TotalGP>0</b:TotalGP>
</b:HotelSearchResult>
<b:HotelSearchResult>
.....
</b:HotelSearchResult>
</a:Results>
<a:Status>Successful</a:Status>
<a:TraceId>b748e818-5c6a-4e41-94ca-f8552a328b99</a:TraceId>
</GetPrice_HotelResult>
</GetPrice_HotelResponse>
</s:Body>
</s:Envelope>
Now I want to create xml like
<?xml version="1.0" encoding="utf-16"?>
<ArrayOfHotelSearchResult xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<HotelSearchResult>
<ResultIndex>1</ResultIndex>
<HotelCode>AMB3|LON</HotelCode>
<HotelName>Ambassadors Bloomsbury</HotelName>
<HotelCategory />
<StarRating>FourStar</StarRating>
<HotelDescription>***Special Offer Free welcome gift for stays of 4 or more nights and free bottle of water in each room </HotelDescription>
<HotelPromotion />
<HotelPolicy />
<HotelPicture>http://images.gta-travel.com/HH/Images/GB/LON/LON-AMB3-1.jpg</HotelPicture>
<HotelAddress>12 UPPER WOBURN PLACE London WC1 0HX United Kingdom, , United Kingdom, </HotelAddress>
<HotelContactNo />
<Latitude />
<Longitude />
<AmountBeforeTax>0</AmountBeforeTax>
<AmountAfterTax>0</AmountAfterTax>
<AmountBeforeDiscount>0</AmountBeforeDiscount>
<AmountBeforeTaxInSupplierCurr>259.00</AmountBeforeTaxInSupplierCurr>
<AmountAfterTaxInSupplierCurr>259.00</AmountAfterTaxInSupplierCurr>
<AmountBeforeDiscountInSupplierCurr>259.00</AmountBeforeDiscountInSupplierCurr>
<BookingSource>GTA</BookingSource>
<CurrencySupplier>GBP</CurrencySupplier>
<PreferredROE>0</PreferredROE>
<IsBaseCurrencyRequired>false</IsBaseCurrencyRequired>
<Price>
<CommissionType>RB</CommissionType>
<PlbType>RB</PlbType>
<OurPlbType>RB</OurPlbType>
<AirlineTransFee>0</AirlineTransFee>
<TdsCommission>0</TdsCommission>
<TDSPLB>0</TDSPLB>
<PriceId>0</PriceId>
<PublishedFare>0</PublishedFare>
<NetFare>0</NetFare>
<Markup>0</Markup>
<ServiceTax>0</ServiceTax>
<CessTax>0</CessTax>
<OurCommission>0</OurCommission>
<OurPLB>0</OurPLB>
<AgentCommission>0</AgentCommission>
<AgentPLB>0</AgentPLB>
<OtherCharges>0</OtherCharges>
<Tax>0</Tax>
<WhiteLabelDiscount>0</WhiteLabelDiscount>
<TransactionFee>0</TransactionFee>
<Currency>INR</Currency>
<ChargeBU />
<AccPriceType>PublishedFare</AccPriceType>
<RateOfExchange>0</RateOfExchange>
<AdditionalTxnFee>0</AdditionalTxnFee>
<WLCharge>0</WLCharge>
<Discount>0</Discount>
<ReverseHandlingCharge>0</ReverseHandlingCharge>
<YQTax>0</YQTax>
<IsServiceTaxOnBaseFarePlusYQ>false</IsServiceTaxOnBaseFarePlusYQ>
<TdsRate>0</TdsRate>
<AgentMarkUpType>Percentage</AgentMarkUpType>
<AgentMarkUp>0</AgentMarkUp>
<AgentMarkUpAmt>0</AgentMarkUpAmt>
<ConvenienceCharges>0</ConvenienceCharges>
<PrfROE>0</PrfROE>
<ServiceTaxRate>0</ServiceTaxRate>
<EduCessRate>0</EduCessRate>
<EduCessAmount>0</EduCessAmount>
<AgentCommissionRate>0</AgentCommissionRate>
<AgentPLBRate>0</AgentPLBRate>
<AirlineBaggageCharges>0</AirlineBaggageCharges>
<AirlineMealCharges>0</AirlineMealCharges>
<AirlineSeatCharges>0</AirlineSeatCharges>
<OurCommRate>0</OurCommRate>
<OurPLBRate>0</OurPLBRate>
<OurIncentiveRate>0</OurIncentiveRate>
<OurIncentiveAmt>0</OurIncentiveAmt>
<SegmentFee>0</SegmentFee>
<OurCommissionType>RB</OurCommissionType>
<OurServiceTaxRate>0</OurServiceTaxRate>
<OurServiceTaxAmt>0</OurServiceTaxAmt>
<OurEduCessRate>0</OurEduCessRate>
<OurEduCessAmt>0</OurEduCessAmt>
<OurTdsRate>0</OurTdsRate>
<IsServiceChargeApplicable>true</IsServiceChargeApplicable>
<OurTdsCommAmt>0</OurTdsCommAmt>
<OurTdsPLBAmt>0</OurTdsPLBAmt>
<IsGPEnabled>false</IsGPEnabled>
<TotalGP>0</TotalGP>
<CateringCharge>0</CateringCharge>
<AgentIncentiveRate>0.00</AgentIncentiveRate>
<AgentIncentiveAmt>0.00</AgentIncentiveAmt>
<TdsIncentive>0.00</TdsIncentive>
<DealId>0</DealId>
<SupplierId>0</SupplierId>
<StockType />
<IsPaidByAgentCreditCard>false</IsPaidByAgentCreditCard>
<AmountPaidByAgentCreditCard>0.00</AmountPaidByAgentCreditCard>
<OurTdsIncentiveAmt>0.00</OurTdsIncentiveAmt>
<IsOurServiceTaxOnComm>false</IsOurServiceTaxOnComm>
<IsOurServiceTaxOnBaseFarePlusYQ>false</IsOurServiceTaxOnBaseFarePlusYQ>
<ServiceFee>0</ServiceFee>
<TotalTxnFee>0</TotalTxnFee>
<SwachhBharatCessRate>0</SwachhBharatCessRate>
<SwachhBharatCessAmount>0</SwachhBharatCessAmount>
</Price>
<RateType>Negotiated</RateType>
<CityName />
<IsDomestic>false</IsDomestic>
<NoOfRooms>0</NoOfRooms>
<NoOfNights>0</NoOfNights>
<IsTBOMapped>false</IsTBOMapped>
<SupplierHotelCodes />
<UAPISessionId>7685eeea-c903-4eb7-ae76-2369f40b635c</UAPISessionId>
<HotelDetails>
<StarRating>All</StarRating>
</HotelDetails>
<BookingMode>NotSet</BookingMode>
</HotelSearchResult>
<HotelSearchResult>
.......
</HotelSearchResult>
</ArrayOfHotelSearchResult>
Can anybody help me in making xslt. Currently I an unable to get any value in xslt and i am also facing problem in debugging in VS2012. Sometimes debugger comes sometimes not.
Here is a start using xml linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication93
{
class Program
{
const string XML_INPUT = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument inputDoc = XDocument.Load(XML_INPUT);
List<XElement> hotelSearchResults = inputDoc.Descendants().Where(x => x.Name.LocalName == "HotelSearchResult").ToList();
XNamespace aNS = hotelSearchResults[0].GetNamespaceOfPrefix("a");
XNamespace bNS = hotelSearchResults[0].GetNamespaceOfPrefix("b");
string header = "<?xml version=\"1.0\" encoding=\"utf-16\"?>" +
"<ArrayOfHotelSearchResult xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
"</ArrayOfHotelSearchResult>";
XDocument doc = XDocument.Parse(header);
XElement arrayOfHotelSearchResult = (XElement)doc.FirstNode;
int count = 0;
foreach (XElement hotelSearchResult in hotelSearchResults)
{
XElement newHotel = new XElement("HotelSearchResult");
arrayOfHotelSearchResult.Add(newHotel);
newHotel.Add(new object[] {
new XElement("ResultIndex", ++count),
new XElement("HotelCode", (string)hotelSearchResult.Descendants(bNS + "HotelCode").FirstOrDefault())
});
XElement price = new XElement("Price");
newHotel.Add(price);
price.Add(new XElement("CommissionType", (string)hotelSearchResult.Descendants(bNS + "CommissionType").FirstOrDefault()));
}
}
}
}
Using XmlReader
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication93
{
class Program
{
const string XML_INPUT = #"c:\temp\test.xml";
static void Main(string[] args)
{
XmlReader reader = XmlReader.Create(XML_INPUT);
XNamespace bNS = "PricingCommonAPI";
while(!reader.EOF)
{
if(reader.Name != "HotelSearchResult")
{
reader.ReadToFollowing("HotelSearchResult", bNS.NamespaceName);
}
if(!reader.EOF)
{
XElement hotelSearchResult = (XElement)XElement.ReadFrom(reader);
}
}
}
}
}
XSLT is a type of stylesheet primarily used to present the data from XML in a human-readable way, usually by putting it into HTML elements.
If you want to convert your existing XML to a new structure, I suggest you use XML tools in C# to deserialize the XML, map it to the new structure and render a new XML.