XDocument Decendants with Namespaces - c#

I have this xml:
<?xml version="1.0" encoding="UTF-8"?>
<CueList xmlns="urn:CueListSchema.xml" xmlns:s="urn:schemas-rcsworks-com:SongSchema" xmlns:n="urn:schemas-rcsworks-com:NoteSchema" xmlns:l="urn:schemas-rcsworks-com:LinkSchema" xmlns:t="urn:schemas-rcsworks-com:TrafficSchema" xmlns:p="urn:schemas-rcsworks-com:ProductSchema" xmlns:m="urn:schemas-rcsworks-com:MediaSchema" xmlns:w="urn:schemas-rcsworks-com:WebPageSchema" xmlns:ns="urn:CueListSchema.xml" time="2011-12-02T13:34:39">
<Event eventID="14" eventType="song" status="happening" scheduledTime="13:34:38" scheduledDuration="332.82">
<s:Song title="Long Time Coming (Holding On)" internalID="007700028007AD480000">
<s:Artist name="The Winans" sequenceNumber="1" internalID="0067000180002B020000" sortName="Winans, The" />
<m:Media ID="{7C734B6C-7AF7-4998-8366-F1F11F5D56D7}" runTime="332.82" fileName="{7C734B6C-7AF7-4998-8366-F1F11F5D56D7}.wav" />
</s:Song>
</Event>
<Event eventID="15" eventType="link" status="committed" startTime="13:40:10" scheduledDuration="3.49">
<l:Link title="PG MFL DRY FEMALE" internalID="007B00028002DAEA0000">
<m:Media ID="{036BB0ED-3130-4AD0-8BAF-E5D0FBA7DC3B}" runTime="3.49" fileName="{036BB0ED-3130-4AD0-8BAF-E5D0FBA7DC3B}.wav" />
</l:Link>
</Event>
<Event eventID="16" eventType="song" status="committed" startTime="13:40:10" scheduledDuration="303.55">
<s:Song title="Not Making Sense, Making Faith" internalID="007700028009377F0000">
<s:Artist name="Donald Lawrence" sequenceNumber="1" internalID="006700018000308A0000" sortName="Lawrence, Donald" />
<m:Media ID="{B6FD04EA-9B42-4E6A-AC80-A26BF65E6F11}" runTime="303.55" fileName="{B6FD04EA-9B42-4E6A-AC80-A26BF65E6F11}.wav" />
</s:Song>
</Event>
</CueList>
I am able to set the namespaces for songs etc. But when I try and select Events it does not work, I tried setting the namespace for CueList and when I debug it says that namespace is null?

It's hard to know what's wrong when you haven't shown the code you're using, but it should be simple:
XNamespace ns = "urn:CueListSchema.xml";
var events = doc.Descendants(ns + "Event");
If that doesn't work, please give us a short but complete example of both the XML (formatted, please, and not just copied from a browser) and code you're using.

Related

keep getting ERR.SWS.CLIENT.VALIDATION_FAILED exception when calling PassengerDetailsRQ

I am using Sabre SOAP Api in C#. I got the response from session creation successfully, I added wsdl Service Reference
http://files.developer.sabre.com/wsdl/sabreXML1.0.00/ServicesPlatform/PassengerDetails3.3.0RQ.wsdl to my test project and pass required values to parameters in the request as given in the documentation https://developer.sabre.com/docs/read/soap_apis/management/itinerary/Passenger_Details.
this is my xml to that is send to sabre and Getting Exception
<?xml version="1.0" encoding="utf-16"?>
<PassengerDetailsRQ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" version="2.2.1"
IgnoreOnError="false">
<MiscSegmentSellRQ xmlns="http://services.sabre.com/sp/pd/v3_2">
<MiscSegment DepartureDateTime="2018-01-10T16:45" InsertAfter="0" NumberInParty="1" Status="HK" Type="OTH">
<OriginLocation LocationCode="SAN" />
<Text>America Tours</Text>
<VendorPrefs>
<Airline Code="DL" />
</VendorPrefs>
</MiscSegment>
</MiscSegmentSellRQ>
<PostProcessing xmlns="http://services.sabre.com/sp/pd/v3_2">
<EndTransactionRQ>
<EndTransaction Ind="true">
<Email Ind="true" />
</EndTransaction>
<Source ReceivedFrom="SWS TESTING" />
</EndTransactionRQ>
</PostProcessing>
<PreProcessing xmlns="http://services.sabre.com/sp/pd/v3_2" />
<PriceQuoteInfo xmlns="http://services.sabre.com/sp/pd/v3_2">
<Link NameNumber="1.1" Record="1" />
</PriceQuoteInfo>
<SpecialReqDetails xmlns="http://services.sabre.com/sp/pd/v3_2">
<SpecialServiceRQ>
<SpecialServiceInfo>
<SecureFlight>
<PersonName DateOfBirth="02/02/1998" NameNumber="1.1">
<GivenName>Usama QW</GivenName>
<Surname>Alam</Surname>
</PersonName>
<VendorPrefs>
<Airline />
</VendorPrefs>
</SecureFlight>
</SpecialServiceInfo>
</SpecialServiceRQ>
</SpecialReqDetails>
<TravelItineraryAddInfoRQ xmlns="http://services.sabre.com/sp/pd/v3_2">
<AgencyInfo>
<Address>
<AddressLine>America Tours</AddressLine>
<CityName>Los Angeles</CityName>
<CountryCode>US</CountryCode>
<PostalCode>90020</PostalCode>
<StateCountyProv StateCode="CA" />
<StreetNmbr>3434 West 6th Street Suite 400-6</StreetNmbr>
</Address>
<Ticketing TicketType="7T-A" />
</AgencyInfo>
<CustomerInfo>
<ContactNumbers>
<ContactNumber NameNumber="1.1" Phone="213-738-8185" PhoneUseType="A" />
<ContactNumber NameNumber="1.1" Phone="3162881034" PhoneUseType="A" />
</ContactNumbers>
<Email Address="www.usamaalam60#gmail.com" ShortText="AmericaTours" />
<Email Address="admin#koreaonly.com" ShortText="AmericaTours" />
<PersonName NameNumber="1.1" NameReference="MR" PassengerType="ADT">
<GivenName>Usama sd</GivenName>
<Surname>Alam</Surname>
</PersonName>
</CustomerInfo>
</TravelItineraryAddInfoRQ>
</PassengerDetailsRQ>
For this one you seem to be using invalid service version for the 3.2 namespace. Try with something like this:
*xmlns="http://services.sabre.com/sp/pd/v3_2"* and *version="3.2.0"*.
You were using version 2.2.1 here which will require a different URL.
Are you intending to use 3.2.0 version? I can see that the dates are not valid as per the schema as well. You have:
*DateOfBirth="02/02/1998"*
but should have:
*DateOfBirth="1998-02-02"*

Reading in a simple XML config file in C#

Im having a hard time remembering how to do this, and most of the examples I'm seeing dont really cover my issue. I'm trying to read in the below XML file, so that if a user selects a Tool Type from a drop-down menu, the variables for said tool will populate a form on screen. I just have no clue how to collect all the elements/attributes for a specific tool.
<?xml version="1.0" encoding="UTF-8"?>
<Tool_menu>
<tool name="A">
<emails>
<email severity="Low">
<address>reg#test.com</address>
</email>
<email severity="High">
<address>notReg#test.com</address>
</email>
</emails>
<configuration_list>
<configuration>
<name>Confg1</name>
</configuration>
<configuration>
<name>Confg2</name>
</configuration>
<configuration>
<name>Confg3</name>
</configuration>
<configuration>
<name>Confg4</name>
</configuration>
</configuration_list>
</tool>
<tool name="B">
<emails>
<email severity="Low">
<address>reg#test.com</address>
</email>
<email severity="High">
<address>notReg#test.com</address>
</email>
</emails>
<configuration_list>
<configuration>
<name>n/a</name>
</configuration>
<configuration>
<name>n/a</name>
</configuration>
</configuration_list>
</tool>
<tool name="C">
<emails>
<email severity="Low">
<address>reg#test.com</address>
</email>
<email severity="High">
<address>notReg#test.com</address>
</email>
</emails>
<configuration_list>
<configuration>
<name>200Scope</name>
</configuration>
<configuration>
<name>300Scope</name>
</configuration>
<configuration>
<name>600Scope</name>
</configuration>
<configuration>
<name>900Scope</name>
</configuration>
</configuration_list>
</tool>
</Tool_menu>
what I'd want is for a user to select 'tool C' and see a list of configurations available on tool C, name of the tool, and a dropdown of options for who to email (low/high severity) that would be tool specific
**using .net 4.5
Access nodes using XPath.
Take a look at some tutorials here or here
In your case, accessing tools C can be achieved like this:
XmlDocument doc = new XmlDocument();
doc.Load(#"c:\temp\tools.xml");
var toolCemails = doc.SelectNodes("//tool[#name='C']/emails/email"); //two nodes with email tag
var toolCconfigs = doc.SelectNodes("//tool[#name='C']/configuration_list/configuration"); //four config nodes
You could take a look at this post on SO: LINQ to read XML
edit: also, in the comments below your question, #zx485 posted a link to another helpful SO post, here: Bind XML data to a Dropdownlist c#
That might help get you started. If not, please try to narrow your question to something more specific - preferably with some code that we can help you with.
As your question is written right now, it seems that you are asking us to do this for you rather than help you with a specific question.

Get and Set XML elements with Namespaces

NEWBIE QUESTION.
I haven't worked that much with xml, nothing like this anyway. I have some XML as shown below that I receive which has several namespaces.
I need to read some values, then update others before returning the revised XML with namespaces intact - don't want them removed.
I am given the path to some of the elements like this cred/sub/aa or trip/items/item[0]/customerInfo/custName.
But it seems that namespaces make it difficult to get to those elements so simply.
Does anybody know how I can read some of the values like NON-SMOKING from custPref or get the value CABBAGE from bossman/zz.
Also, I want to be able to then set a value such as custName to say Mr. X.
Any ideas?
Thanks.
<?xml version="1.0" encoding="utf-16" ?>
<A1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<cred xmlns="https://blah-blah.com/?foobar">
<sub>
<aa>Zippo</aa>
<bb>lighter</bb>
</sub>
<reqId>
<cc></cc>
<dateOfBirth></dateOfBirth>
</reqId>
</cred>
<reqName xmlns="http://blah-blah/vader/base">qwerty</reqName>
<reqId xmlns="http://blah-blah/vader/base">12345</reqId>
<machine xmlns="http://blah-blah/vader/base">
<qqq>hello</qqq>
<www>goodbye</www>
<eee>99999</eee>
<rrr>88888</rrr>
</machine>
<monkey xmlns="http://blah-blah/vader/base">alskdjfhg</monkey>
<math xmlns="http://blah-blah/vader/base">
<language></language>
</math>
<trip xmlns="http://blah-blah/simple">
<tripOverview xmlns="http://blah-blah/vader/base">
<description></description>
<cost></cost>
</tripOverview>
<bossman xmlns="http://blah-blah/vader/base">
<zz>CABBAGE</zz>
<yy>BANANA</yy>
<xx>MELON</xx>
<ww>SYRUP</ww>
</bossman>
<items>
<item>
<itemSummary xmlns="http://blah-blah/vader/base">
<description></description>
<cost></cost>
<reference></reference>
</itemSummary>
<customerInfo xmlns="http://blah-blah/vader/base">
<custName></custName>
<custPref>NON-SMOKING</custPref>
</customerInfo>
<seatId xmlns="http://blah-blah/vader/base">1</seatId>
</item>
</items>
</trip>
</A1>
string xml = "<Root><Options></Options></Root>";
var xdocs = XDocument.Parse(xml);
xdocs.Descendants().Where(q => q.Name == "Options").FirstOrDefault().Value = "FoundIt";

How can i remove Nodes of Manifest-File created with Mage.exe/MageUI.exe without getting trouble with the namespace?

In the Last few Days i tried to .Remove(); some Nodes in a Manifest-File , to specify the Problem i tried to delete the Populated-Files in a Manifest-File with a C# programm.
If you don't know exactly what a Populated file is i will explain it as good as i can:
A Populated File is a File (example: "Populated-File.txt.deploy") wich one you need for you're Manifest-File, because without Populated-Files your Application won't do that much. When you press the "Populate"-Button in the MageUI.exe or you set the Option "-FromDirectory" in the Mage.exe you will add Nodes in the Manifest-File, they are called <dependency dependencyType="install"></dependency> and <file></file>. In these Nodes are Informations about the Populated-Files(example: name="Populated-File.txt.deploy" size="123" location="..."and so on).
These Nodes are in the Manifest-File just like that:
Attention should be paid to the 2nd Node : <asmv1:assembly>, because that is default if the Manifest-File got created with MageUi.exe/ Mage.exe, there starts the Problem.
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
<asmv1:assemblyIdentity name="Example.exe" />
<description asmv2:iconFile="Example.ico" xmlns="urn:schemas-microsoft-com:asm.v1" />
<dependency>
<dependentAssembly dependencyType="install" size="123">
</dependentAssembly>
</dependency>
<file name="PopulatedFile.dll.deploy" size="123">
</file>
</asmv1:assembly>
After a while I got it, with some help from this Forum.
//does currently only delete the "<dependency></dependency>"-Node
xml.Descendants().Where(x => x.Name.LocalName == "dependentAssembly" && (string)x.Attribute("dependencyType") == "install").Select(x => x.Parent).Remove();
xml.Save(filePath);
So far so good, but as i added .Remove(); for the <file></file>-Node that the Code looked like that:
xml.Descendants().Where(x => x.Name.LocalName == "dependentAssembly" && (string)x.Attribute("dependencyType") == "install").Select(x => x.Parent).Remove();
xml.Descendants().Where(x => x.Name == "file").Remove();
xml.Save(filePath);
I noticed that the Manifest-File has added, infront of almost every Node, asmv2: and the <dependency>-Nodes got deleted. It would be better when <dependency>/<file>-Nodes get deleted and there would be any asmv2.
Just like that:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd" manifestVersion="1.0" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3" xmlns:dsig="http://www.w3.org/2000/09/xmldsig#" xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
<asmv1:assemblyIdentity name="Example.exe" />
<description asmv2:iconFile="Example.ico" xmlns="urn:schemas-microsoft-com:asm.v1" />
<asmv2:file name="PopulatedFile.dll.deploy" size="123">
</asmv2:file>
</asmv1:assembly>
The consiquence is that the File is not openable anymore with MageUi.exe.
So i started to research also on this Forum, and got as answer its the Namespace.
xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
So finally:
My question is How could i solve this?
As always: You can edit this so it gets more specific or even more correnct (maybe i didn't explained the Populate-Files right)
Please correct me in any way but be constructive :)
Okay, it looks like LINQ to XML is getting confused because the namespace is declared twice in the root element - once as the default namespace, and once with an alias of asmv2. The simplest solution is just to remove that attribute.
To be honest, MageUI should cope with it anyway - it's representing the right data. Yet another program that doesn't look at the XML properly, apparently. (Sigh...)
I'd also look for descendants with the right name (in the right namespace) rather than looking for a particular LocalName. For example:
var doc = XDocument.Load("test.xml");
doc.Root.Attribute(XNamespace.Xmlns + "asmv2").Remove();
XNamespace ns = "urn:schemas-microsoft-com:asm.v2";
doc.Descendants(ns + "dependentAssembly")
.Where(x => (string)x.Attribute("dependencyType") == "install")
.Select(x => x.Parent)
.Remove();
doc.Descendants(ns + "file").Remove();
doc.Save("test2.xml");
Output (reformatted a little):
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly
xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd"
manifestVersion="1.0"
xmlns:asmv1="urn:schemas-microsoft-com:asm.v1"
xmlns="urn:schemas-microsoft-com:asm.v2"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:co.v1="urn:schemas-microsoft-com:clickonce.v1"
xmlns:asmv3="urn:schemas-microsoft-com:asm.v3"
xmlns:dsig="http://www.w3.org/2000/09/xmldsig#"
xmlns:co.v2="urn:schemas-microsoft-com:clickonce.v2">
<asmv1:assemblyIdentity name="Example.exe" />
<description p8:iconFile="Example.ico"
xmlns="urn:schemas-microsoft-com:asm.v1"
xmlns:p8="urn:schemas-microsoft-com:asm.v2" />
</asmv1:assembly>

How to insert a child element into an existing element

I am using a XDocument to write an xml file and I am writing to the document in two different places. After the first write I have
<?xml version="1.0" encoding="utf-8"?>
<suspensedata connectionid="000" customerid="000" name="MyName" />
After the second write I want the file to look like this
<?xml version="1.0" encoding="utf-8"?>
<suspensedata connectionid="560" customerid="131" name="ImgTransfer2327">
<transaction DocumentID="46" SuspenseID="7">
<field id="LocationID">000000015000</field>
<field id="AccountNumber">50000</field>
<field id="AmountPaid">25.00</field>
<field id="CheckAmount">100.00</field>
<field id="CheckNo">000</field>
</transaction>
</suspensedata>
But I can't seem to get the insert done correctly.
I've tried (The name of my XDocument is ValidXml) ValidXml.Root.Add(new Element("transaction"));
and that does not change anything.
I have also tried ValidXml.Element("suspensedata").Add(new XElement("transaction"));
But that did not work either.
How would I add this child element?
EDIT: Both attempts did not produce any other output besides the output on the first try. Also I did make sure to use ValidXml.Save()
I have tried something like this I supposed that the two parts are in 2 files
//xmlfile1 contains the first part
<?xml version="1.0" encoding="utf-8"?>
<suspensedata connectionid="000" customerid="000" name="MyName" />
//this part will be loaded like this
XDocument xDoc = XDocument.Load("xmlfile1.xml");
XElement elt = xDoc.Root;
//and the second file contains the second part
XDocument xDoc2 = XDocument.Load("xmlfile2.xml");
XElement elt2 = xDoc2.Root;
elt.Add(elt2);
xDoc.Save("xmlfile1.xml");
Hope this help

Categories