Modify soap response conditionally - c#

I wanted to modify/delete node from the soap response xml on the basis of Country passed as a parameter, here in this xml I wanted to delete node if the Country=”US”.
I tried using the below code but it did not select nodes.
XDocument doc = XDocument.Parse(“XMLString”));
XNamespace xmlns = " http://schemas.xmlsoap.org/soap/envelope/";
var addressNode = doc.Descendants(xmlns + " AddressData").Elements(xmlns + " Country");
Can anybody suggest approach to delete node on the basis of Country.
Sample Xml:
<?xml version="1.0" encoding="UTF-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<GetAddressDataRs xmlns="xyz.com/Services/Schemas/ Address /v1" xmlns:cm="xyz.com/Services/Schemas/Common/v1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="xyz.com/Services/Schemas/Address /Schemas.xsd">
<AddressData>
<Id xsi:type="xsd:string">1</Id>
<Add1>ABCDEFG</Add1>
<Add2>XYZABV</Add2>
<City>Las Vegas</City>
<Country>US</Country>
</AddressData>
<AddressData>
<Id xsi:type="xsd:string">1</Id>
<Add1>ABCDEFG</Add1>
<Add2>XYZABV</Add2>
<City>Phoenix</City>
<Country>US</Country>
</AddressData>
<AddressData>
<Id xsi:type="xsd:string">1</Id>
<Add1>ABCDEFG</Add1>
<Add2>XYZABV</Add2>
<City>Kansas City</City>
<Country>US</Country>
</AddressData>
<AddressData>
<Id xsi:type="xsd:string">1</Id>
<Add1>ABCDEFG</Add1>
<Add2>XYZABV</Add2>
<City>Sydney</City>
<Country>Australia</Country>
</AddressData>
<AddressData>
<Id xsi:type="xsd:string">1</Id>
<Add1>ABCDEFG</Add1>
<Add2>XYZABV</Add2>
<City>Townsville</City>
<Country>Australia</Country>
</AddressData>
</GetAddressDataRs>
</s:Body>
</s:Envelope>

Try following xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Xml;
using System.Xml.Linq ;
namespace ConsoleApplication91
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var usa = doc.Descendants().Where(x => x.Name.LocalName == "AddressData").Where(x => x.Elements().Any(y => (y.Name.LocalName == "Country") && ((string)y == "US"))).FirstOrDefault();
}
}
}

Related

get decendents in XML where specific element contains value

<?xml version="1.0" encoding="utf-8" ?>
<Licenses>
<License>
<LicenseType>Temporary License</LicenseType>
<BundleType>Line</BundleType>
<Features>
<Feature>
<Value>Full</Value>
<Status>Full Access</Status>
<AccessLevel>Full</AccessLevel>
</Feature>
<Feature>
<Name>EnhancedUserAccounts</Name>
<LocalisedName>Enhanced User Accounts</LocalisedName>
<Value>Full</Value>
<Status>Full Access</Status>
<AccessLevel>Full</AccessLevel>
</Feature>
</Features>
</License>
<License>
<LicenseType>Temporary License</LicenseType>
<BundleType>Line</BundleType>
<Features>
<Feature>
<Value>Full</Value>
<Status>Full Access</Status>
<AccessLevel>Full</AccessLevel>
</Feature>
<Feature>
<Name>EnhancedUserAccounts</Name>
<LocalisedName>Enhanced User Accounts</LocalisedName>
<Value>Full</Value>
<Status>Full Access</Status>
<AccessLevel>Full</AccessLevel>
</Feature>
</Features>
</License>
</Licenses>
How to read the feature list into to IEnumerable if my BundleType = line
You can do this easily using XDocument
var xDocument = XDocument.Parse(XML)
or
var xDocument = XDocuemnt.Load(FilePath)
then:
xDocument.Descendants("LicenseType")
Which will get all nodes that descend from LicenseType
To test for that BundleType element you could do something like:
nodes.Where(n=>n.Element("BundleType") == "Line").Decesendants("Features")
which will get all Features where <BundleType> of the parent is "Line"
EDIT: As per comments, to get all features:
xDocument.Desecendants("Features")
That will get all <Feature> nodes under the <Features> Element
Use following based on the xml I updated on your posting :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication70
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("License").Where(x => (string)x.Element("BundleType") == "Line")
.Select(x => x.Descendants("Feature").ToList()).ToList();
}
}
}

XML to Linq C# retrieve entries from XML

I need to to the following task:
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<Eintrag>
<Kunde>
<Email> example#test.de </Email>
<Kundennummer>1234567 </Kundennummer>
</Kunde>
<Kunde>
<Email> example1#test.de </Email>
<Kundennummer>1234569 </Kundennummer>
</Kunde>
</Eintrag>
I need to save Email and Kundennummer of each Kunde in a String.
Can you please tell me how to do it?
Try following :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication62
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
var results = doc.Descendants("Kunde").Select(x => new
{
email = (string)x.Element("Email"),
num = (string)x.Element("Kundennummer")
}).ToList();
}
}
}

Trying to transform XMl to XML using XSL with C# Console App

I have an XML file - for testing:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<StudentHistory xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<Item>
<Week>1988-05-12</Week>
<Name>A</Name>
<Counsel>1</Counsel>
<Completed>1</Completed>
<Description>XX</Description>
</Item>
<Item>
<Week>1988-05-12</Week>
<Name>AA</Name>
<Counsel>2</Counsel>
<Completed>1</Completed>
<Description>XX</Description>
</Item>
<Item>
<Week>1988-05-13</Week>
<Name>B</Name>
<Counsel>2</Counsel>
<Completed>1</Completed>
<Description>XX</Description>
</Item>
<Item>
<Week>1988-05-14</Week>
<Name>C</Name>
<Counsel>3</Counsel>
<Completed>1</Completed>
<Description>XX</Description>
</Item>
<Item>
<Week>1988-05-15</Week>
<Name>D</Name>
<Counsel>4</Counsel>
<Completed>1</Completed>
<Description>XX</Description>
</Item>
<Item>
<Week>1988-05-16</Week>
<Name>E</Name>
<Counsel>5</Counsel>
<Completed>1</Completed>
<Description>XX</Description>
</Item>
<Item>
<Week>1988-05-17</Week>
<Name>F</Name>
<Counsel>6</Counsel>
<Completed>1</Completed>
<Description>XX</Description>
</Item>
<Item>
<Week>1988-05-18</Week>
<Name>G</Name>
<Counsel>7</Counsel>
<Completed>0</Completed>
<Description>XX</Description>
</Item>
<Item>
<Week>2018-01-16</Week>
<Name>H</Name>
<Counsel>-1</Counsel>
<Completed>1</Completed>
<Description>XX</Description>
</Item>
</StudentHistory>
In the final file I will have many entries with the same "Week". So I followed a tutorial and am just testing at this stage. I came up with this:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="items-by-week" match="Item" use="Week" />
<xsl:template match="StudentHistory/Item">
<xsl:for-each select="Item[count(. | key('items-by-week', Week)[1]) = 1]">
<xsl:sort select="Week" />
<xsl:value-of select="Week" />
<xsl:for-each select="key('items-by-week', Week)">
<xsl:sort select="Name" />
<xsl:value-of select="Name" /> (<xsl:value-of select="Counsel" />)
</xsl:for-each>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
I wrote a C# console application that does this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Xsl;
namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
var myXslTrans = new XslCompiledTransform();
myXslTrans.Load(#"d:\TestTransform2.xsl");
myXslTrans.Transform(#"d:\Test-Students2.xml", #"d:\Test-Students2-Final.xml");
}
}
}
When I run it my output xml is empty. What have I overlooked? It should have written something out with the names grouped by week.
The first part is real simple using xml linq :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XNamespace ns = doc.Root.GetDefaultNamespace();
List<Student> students = doc.Descendants(ns + "Item").Select(x => new Student() {
week = (DateTime)x.Element(ns + "Week"),
name = (string)x.Element(ns + "Name"),
counsel = (int)x.Element(ns + "Counsel"),
completed = (int)x.Element(ns + "Completed") == 1 ? true : false,
description = (string)x.Element(ns + "Description")
}).ToList();
var weeks = students.GroupBy(x => x.week).ToList();
}
}
public class Student
{
public DateTime week { get; set;}
public string name { get; set; }
public int counsel { get; set; }
public Boolean completed { get; set; }
public string description { get; set; }
}
}

XML C# Parse - Complex

I have been on google for a while but am just stumped. I need to parse xml of this nature. I can't seem to skip to elements in the middle, e.g. Folder. I have limited the xml as there were many 'Folder' elements. Any guidance would be appreciated. I was after the FolderID element's attribute ID.
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<h:ServerVersionInfo MajorVersion="14"
MinorVersion="1"
MajorBuildNumber="225"
MinorBuildNumber="46"
Version="Exchange2010_SP1"
xmlns:h="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns="http://schemas.microsoft.com/exchange/services/2006/types"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" />
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<m:GetFolderResponse xmlns:m="http://schemas.microsoft.com/exchange/services/2006/messages"
xmlns:t="http://schemas.microsoft.com/exchange/services/2006/types">
<m:ResponseMessages>
<m:GetFolderResponseMessage ResponseClass="Success">
<m:ResponseCode>NoError</m:ResponseCode>
<m:Folders>
<t:Folder>
<t:FolderId Id="AAMkADk5MmY1ZThmLTM2MzAtNGVh" ChangeKey="AQAAABYAAACSe/NBrSZiQKqHx8yL+lIRAAAA1EWM" />
<t:ParentFolderId Id="AAMkADk5MmY1ZThmLTM2MzAtNGVh" ChangeKey="AQAAAA==" />
<t:DisplayName>Top of Information Store</t:DisplayName>
<t:TotalCount>0</t:TotalCount>
<t:ChildFolderCount>15</t:ChildFolderCount>
<t:EffectiveRights>
<t:CreateAssociated>true</t:CreateAssociated>
<t:CreateContents>true</t:CreateContents>
<t:CreateHierarchy>true</t:CreateHierarchy>
<t:Delete>true</t:Delete>
<t:Modify>true</t:Modify>
<t:Read>true</t:Read>
<t:ViewPrivateItems>true</t:ViewPrivateItems>
</t:EffectiveRights>
<t:PermissionSet>
<t:Permissions>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Default</t:DistinguishedUser>
</t:UserId>
<t:CanCreateItems>false</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
<t:Permission>
<t:UserId>
<t:DistinguishedUser>Anonymous</t:DistinguishedUser>
</t:UserId>
<t:CanCreateItems>false</t:CanCreateItems>
<t:CanCreateSubFolders>false</t:CanCreateSubFolders>
<t:IsFolderOwner>false</t:IsFolderOwner>
<t:IsFolderVisible>false</t:IsFolderVisible>
<t:IsFolderContact>false</t:IsFolderContact>
<t:EditItems>None</t:EditItems>
<t:DeleteItems>None</t:DeleteItems>
<t:ReadItems>None</t:ReadItems>
<t:PermissionLevel>None</t:PermissionLevel>
</t:Permission>
</t:Permissions>
</t:PermissionSet>
<t:UnreadCount>0</t:UnreadCount>
</t:Folder>
</m:Folders>
</m:GetFolderResponseMessage>
</m:ResponseMessages>
</m:GetFolderResponse>
</s:Body>
</s:Envelope>
LINQ to XML is the best .NET XML Parsing API.
See
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/xdocument-class-overview
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Linq;
namespace ConsoleApp12
{
class Program
{
static void Main(string[] args)
{
var doc = XDocument.Load(#"c:\temp\foo.xml");
var ns = (XNamespace)"http://schemas.microsoft.com/exchange/services/2006/types";
var folders = doc.Descendants(ns + "Folder");
foreach (var e in folders)
{
var folderId = e.Element(ns + "FolderId").Attribute("Id").Value;
Console.WriteLine(folderId);
}
Console.WriteLine("Hit any key to exit.");
Console.ReadKey();
}
}
}
You should learn about serlialization. It's very easy to convert an XML to and from a object in C#. https://www.codeproject.com/Articles/483055/XML-Serialization-and-Deserialization-Part
That said, this will get you the data you're after. It's not very reusable and won't help you with any xml files other than ones with one instance of that attribute, but it's what you're after so here you go.
string FolderId;
string ChangeKey;
using (StreamReader sr = new StreamReader("c:\\myfile.xml"))
{
string line;
while ((line = sr.ReadLine()) != null)
{
if (line.Contains("<t:FolderId Id="))
{
try
{
var lineArray = line.Split('\"');
FolderId = lineArray[1];
ChangeKey = lineArray[3];
}
catch
{
// handle exception
}
}
}
}
You can use the XSD.exe to create a schema class. and then using XML deserializer, you can deserialize/parse xml to object
Using xml linq
XDocument doc = XDocument.Load(FILENAME);
List<XElement> folders = doc.Descendants().Where(x => x.Name.LocalName == "Folder").ToList();
XNamespace tNs = folders.FirstOrDefault().GetNamespaceOfPrefix("t");
XElement id_AAMkADk5MmY1ZThmLTM2MzAtNGVh = folders.Where(x => (string)x.Element(tNs + "FolderId").Attribute("Id") == "AAMkADk5MmY1ZThmLTM2MzAtNGVh").FirstOrDefault();

cannot get node by using selectSingleNode method

my xml file is like below:
<?xml version="1.0"?>
<UpdateInboundim613Response xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" status="SUCCESS" message="Success" schemaRevisionDate="2016-07-19" schemaRevisionLevel="0" returnCode="0" xmlns="http://schemas.hp.com/SM/7">
<model>
<keys>
<TransactionID type="String">E-InHPSXIM1089779</TransactionID>
</keys>
<instance uniquequery="TransactionID="E-InHPSXIM1089779"" recordid="E-InHPSXIM1089779">
<TransactionDetailedTrace xsi:nil="true" />
<TransactionMessage type="Array">
<TransactionMessage type="String" />
</TransactionMessage>
<OVSCSolutionDescription type="Array">
<OVSCSolutionDescription type="String">Issue: EL-BANK OUTSIDE WAREHOUSE EGYPT IMEA[2702]Interface[[E1 0/0/0]]|Router|ELBKCE1GW /pg-h-pg1252-256675160|143.34.213.18|Down Solution: As per update from Mai Shrief that the site has been suspended on 30th June. So no need of any investigation. Resolved By: BT NOC</OVSCSolutionDescription>
</OVSCSolutionDescription>
<OVSCTicketID type="String">E-IM004004076</OVSCTicketID>
<RIMSImpact xsi:nil="true" />
<attachments />
</instance>
</model>
<messages>
<message type="String" xmlns="http://schemas.hp.com/SM/7/Common">TransactionStatusDetail in $L.file is:IM Ticket: E-IM004004076 is valid for Update Subtype: Resolve</message>
</messages>
</UpdateInboundim613Response>
but my code cannot get value of element "OVSCTicketID":
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"C:\zzx\Project\SM\R5.1\Harness\InBound.xml");
XmlNode sigNode = xmlDoc.SelectSingleNode("/UpdateInboundim613Response/model/instance/OVSCTicketID");
if (sigNode != null)
{
Console.WriteLine(sigNode.InnerText);
}
can you please tell me what's the problem and how to fix it?
Your Xml document uses the default namespace "http://schemas.hp.com/SM/7". You need to use the XmlNamespaceManager to select that node under this namespace.
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(#"C:\zzx\Project\SM\R5.1\Harness\InBound.xml");
var namespaceManager = new XmlNamespaceManager(xmlDoc.NameTable);
namespaceManager.AddNamespace("ns", "http://schemas.hp.com/SM/7");
XmlNode sigNode = xmlDoc.SelectSingleNode("//ns:UpdateInboundim613Response//ns:model//ns:instance//ns:OVSCTicketID",namespaceManager);
if (sigNode != null)
{
Console.WriteLine(sigNode.InnerText);
}
Above code should work fine.
Using xml linq
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication1
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XNamespace defaultNs = ((XElement)doc.FirstNode).GetDefaultNamespace();
string ovsCTicketID = (string)doc.Descendants(defaultNs + "OVSCTicketID").FirstOrDefault();
}
}
}

Categories