How do I add a namespace to only ref elements in C#? - c#

I have an XElement which contains the content that I want. However, I want to add a namespace prefix to only the ref elements. Is this possible in C#?
For example, the original XML looks like this:
<Root>
<Element1 />
<Element2 />
<Element3>
<Element3_Child1 />
<Element3_Child2 />
</Element3>
<Element4 />
<Element5>
<Element5_Child1>
<Element5_Child1_Child51 />
</Element5_Child1>
</Element5>
</Root>
I want to add a namespace prefix, so that the XML looks as below
<Root>
<Element1 />
<Element2 />
<ns:Element3>
<Element3_Child1 />
<Element3_Child2 />
</Element3>
<Element4 />
<ns:Element5>
<ns:Element5_Child1>
<Element5_Child1_Child51 />
</Element5_Child1>
</Element5>
</Root>

You can do as stated here : http://www.w3schools.com/xml/xml_namespaces.asp
<root
xmlns:foo="http://www.example.org/foo"
xmlns:bar="http://www.example.org/bar">
However, I'm pretty sure you'll need a valid URI and that you can't "fake" one. Otherwise, the namespace will be invalid. But you can test and let us know.

Related

Obfuscar - skip obfuscation of anonymous types

I'm using the open source obfuscation software "Obfuscar". Is there a way to configure it to not obfuscate the property names in my anonymous types?
I'm using RestSharp to send HTTP requests, and my Json body content is an anonymous type.
request.AddJsonBody(new {
data = new {
type = "attachments",
attributes = new {
name = "foo"
}
}
});
I would like it to NOT rename those properties like "data", "type" etc in the anonymous type, because renaming them affects the Json string that it gets serialized to.
In github obfuscar issues i found this answer and it worked for me
You need to create the node in Obfuscar xml configuration file:
<SkipType name="*AnonymousType*" skipProperties="true" skipMethods="true" skipFields="true" skipEvents="true" skipStringHiding="true" />
Example of full xml configuration file:
<?xml version="1.0" encoding="utf-8"?>
<Obfuscator>
<Var name="OutPath" value="C:\TMP" />
<AssemblySearchPath path="C:\Users\user\Documents\Projects\MyProject\bin\Release\net6.0" />
<AssemblySearchPath path="C:\Program Files\dotnet\shared\Microsoft.NETCore.App\6.0.0" />
<Module file="C:\Users\user\Documents\Projects\MyProject\bin\Release\net6.0\MyProject.dll">
<SkipType name="*AnonymousType*" skipProperties="true" skipMethods="true" skipFields="true" skipEvents="true" />
</Module>
<Var name="KeepPublicApi" value="false" />
<Var name="HidePrivateApi" value="true" />
</Obfuscator>
Next, you need to start obfuscar.exe -s "path_to_xml_configuration_file"
Also see the section in the Obfuscar documentation
https://docs.obfuscar.com/getting-started/configuration#exclusion-rules-by-configuration

StructureFareRulesRQ Parse Failure - Visual Studio Web Reference Naming Convention Error?

I'm trying to call the StructureFareRulesRQ API from Sabre but its seems as though this API is different than the rest of the Sabre APIs. After adding the wsdl file to my project, I am expecting the Web Service call method to be named something like StructureFareRulesRQService but that doesn't exist. Instead I get StructureFareRulesRQ as the actual service and StructureFareRulesRQ1 as the wrapper class for the XML message. As the wrapper class has the wrong name, when it gets serialized, it creates a bogus XML message (see below).
I know I can probably dig through the reference.cs file and do a find/replace, but I'm concerned that doing that will require me to do the same thing whenever a new version comes online. Has anyone else run into this, or am I going nuts?
Example XML Payload which returns a "Error ErrorCode="009400" ErrorMessage="PARSE FAILURE - INVALID REQUEST" response from Sabre:
<?xml version="1.0" encoding="utf-16"?>
<StructureFareRulesRQ1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<PriceRequestInformation CurrencyCode="USD" BuyingDate="2019-05-21T13:46:00" xmlns="http://webservices.sabre.com/sabreXML/2003/07">
<PassengerTypes>
<PassengerType Code="ADT" />
</PassengerTypes>
<ReturnAllData />
</PriceRequestInformation>
<AirItinerary xmlns="http://webservices.sabre.com/sabreXML/2003/07">
<OriginDestinationOptions>
<OriginDestinationOption>
<FlightSegment SegmentType="A" DepartureDate="2019-08-17T17:35:00" BookingDate="2019-05-21T13:46:00" RealReservationStatus="SS">
<DepartureAirport LocationCode="ORD" />
<ArrivalAirport LocationCode="HEL" />
<MarketingAirline Code="AY" />
<OperatingAirline Code="AY" />
</FlightSegment>
<PaxTypeInformation FareBasisCode="IFLE2US2" PassengerType="ADT" FareComponentNumber="0" />
</OriginDestinationOption>
<OriginDestinationOption>
<FlightSegment SegmentType="A" DepartureDate="2019-08-18T13:25:00" BookingDate="2019-05-21T13:46:00" RealReservationStatus="SS">
<DepartureAirport LocationCode="HEL" />
<ArrivalAirport LocationCode="SVO" />
<MarketingAirline Code="AY" />
<OperatingAirline Code="SU" />
</FlightSegment>
<PaxTypeInformation FareBasisCode="IFLE2US2" PassengerType="ADT" FareComponentNumber="0" />
</OriginDestinationOption>
<OriginDestinationOption>
<FlightSegment SegmentType="A" DepartureDate="2019-08-29T10:40:00" BookingDate="2019-05-21T13:46:00" RealReservationStatus="SS">
<DepartureAirport LocationCode="SVO" />
<ArrivalAirport LocationCode="HEL" />
<MarketingAirline Code="AY" />
<OperatingAirline Code="SU" />
</FlightSegment>
<PaxTypeInformation FareBasisCode="IFLE2US2" PassengerType="ADT" FareComponentNumber="0" />
</OriginDestinationOption>
<OriginDestinationOption>
<FlightSegment SegmentType="A" DepartureDate="2019-08-29T13:55:00" BookingDate="2019-05-21T13:46:00" RealReservationStatus="SS">
<DepartureAirport LocationCode="HEL" />
<ArrivalAirport LocationCode="ORD" />
<MarketingAirline Code="AY" />
<OperatingAirline Code="AY" />
</FlightSegment>
<PaxTypeInformation FareBasisCode="IFLE2US2" PassengerType="ADT" FareComponentNumber="0" />
</OriginDestinationOption>
</OriginDestinationOptions>
</AirItinerary>
</StructureFareRulesRQ1>
Hello i think StructureFareRulesRQ1 must be StructureFareRulesRQ.
https://beta.developer.sabre.com/docs/soap_apis/air/utility/get_structured_fare_rules

C# String with [#]

i am here to ask if there are any ways to put variables inside "#" Strings in C#.
Such that the id in the following code, can be changeable.
string xml = #"
<S>
<child id='1'/>
<child id='2'>
<grandchild id='3' />
<grandchild id='4' />
</child>
</S>";
take a look at the string.Format method
var result = string.Format(#"<S>
<child id='{0}'/>
<child id='{1}'>
<grandchild id='{2}' />
<grandchild id='{3}' />
</child>
</S>", id1, id2, id3, id4);
Not directly (C# doesn't have interpolation), but you can pass an #-string to string.Format or string.Concat. (or, for the masochasists, Regex.Replace)
You can use string.Format:
string.Format(#"<S>
<child id='{0}'/>
<child id='{1}'>
<grandchild id='3' />
<grandchild id='4' />
</child>
</S>", childId1, childId2);
Use string.Format() to insert values into your string at runtime. More info about it can be found on MSDN.
string xml = string.Format(#"
<S>
<child id='{0}'/>
<child id='{1}'>
<grandchild id='{2}' />
<grandchild id='{3}' />
</child>
</S>", id1, id2, id3, id4);
This isn't the recommended way to create XML though since you will have to make sure that any value you insert is properly escaped for it's location but as long as you are strictly inserting numerical values this shouldn't be a problem.

XML Serialization in .NET - what's wrong with this

I have xml like this:
<?xml version="1.0" encoding="utf-8"?>
<session xmlns="http://winscp.net/schema/session/1.0" name="blah#blah.com" start="2011-10-03T15:09:30.481Z">
<ls>
<destination value="/incoming/monthly" />
<files>
<file>
<filename value="2.txt" />
<type value="D" />
<modification value="2011-09-14T12:58:26.000Z" />
<permissions value="rwxr-xr-x" />
</file>
<file>
<filename value="3.txt" />
<type value="D" />
<modification value="2011-01-03T22:04:55.000Z" />
<permissions value="rwxr-xr-x" />
</file>
</files>
<result success="true" />
</ls>
</session>
My representation of the following is:
<XmlRoot("session", Namespace:="http://winscp.net/schema/session/1.0")>
Class XMLSession
<XmlElement("ls/files/file")>
Public Property FileList As New List(Of XMLFile)
End Class
<XmlType("file")>
Class XMLFile
<XmlElement("filename")>
Public Property FileName As XMLValueAttribute
<XmlElement("type")>
Public Property TypeName As XMLValueAttribute
<XmlElement("permissions")>
Public Property Permissions As XMLValueAttribute
<XmlElement("modification")>
Public Property ModificationDate As XMLValueAttribute
End Class
Class XMLValueAttribute
<XmlAttribute("value")>
Public Property Value As String
End Class
Why is XMLSession.FileList.Count always 0. I hypothesize it has something to do with the declaration above it but I am not sure what is wrong with it. Maybe it can't accept a path, if not, how can I do it?
You can't describe multiple levels of XML with a single XmlElementAttribute. You need classes for each level.
If you don't want to build the classes by hand, you can get the tools to do it for you:
Assuming your XML is saved in data.xml:
xsd.exe data.xml
This will give you data.xsd which defines the XML.
xsd.exe /l:VB /n:SomeNamespace /c data.xsd
This will give you a codefile data.vb with your types defined, which you can add to your project.
Problem with this one is that there's some kind of bug, described here, which throws an error when you create a serializer around this new type. So you just need one manual tweak on the generated code, changing:
<XmlArrayItemAttribute("file", GetType(sessionLSFilesFile), IsNullable:=False)> _
'To
<XmlArrayItemAttribute("file", GetType(sessionLSFilesFile()), IsNullable:=False)> _

creating a "join" to update one XElement from another XElement

I have an XElement, called "XUsers", that will contain XML which looks like this:
<users>
<user id="12345" name="Bob Smith" />
<user id="67890" name="Jamal Stevens" />
<user id="54321" name="Mary Jones" />
</users>
...and another XElement, called "XTasks", that will contain data like this:
<tasks>
<task id="1" title="Task 1" ownerId="54321" />
<task id="2" title="Task 2" ownerId="12345" />
<task id="3" title="Task 3" ownerId="67890" />
</tasks>
I want to add an attribute ("ownerName") to the task elements in the second XElement (XTasks), and set its values according to a "join" with the first XElement (XUsers). So, my final result will be that the XML in XTask will look like this:
<tasks>
<task id="1" title="Task 1" ownerId="54321" ownerName="Mary Jones" />
<task id="2" title="Task 2" ownerId="12345" ownerName="Bob Smith" />
<task id="3" title="Task 3" ownerId="67890" ownerName="Jamal Stevens" />
</tasks>
Is this possible using Linq? I haven't been able to find any examples of this sort of operation on the web. What is the most efficient way to accomplish this in my ASP.NET(C#) code?
Thanks for any advice you can give.
I am doing this without any IDE in front of me, so forgive me for any errors..
foreach (XElement task in XTasks.Elements())
{
XElement userNode = XUsers.Elements().Where(
e => e.Attribute("id").Value == task.Attribute("ownerId").Value).FirstOrDefault();
if (userNode != null)
{
task.Attribute("ownerName").SetValue(userNode.name);
}
}

Categories

Resources