I have an "xml-source" that is sending me XML.
The xml can come in two ways. One that is "Order" related. A second that is "Employee" related.
Typically, when I shred xml, I use some Linq-To-Xml to parse a known xml-schema.
But now, with 2 different xml-schema's coming at me, I am trying to find the most efficient way to "traffic cop" the Xml.
What I've tried is:
Parse "version1".........and then check for mandatory (order) data (like valid OrderId's). If that data isn't there, then:
Parse for "version2"........then check for mandatory employee data, like employeeSSN.
If both fail, then I log that I didn't get either.
Any ideas on what is the most efficient way to do this traffic copping of the Xml?
My other idea is the create xsd's, and validate. But then I'm running a xsd-validate....and then sending it to a "parser".....so that may be less efficient than the idea above...of try1, try2, then fail.
While I can choose when I traffic-cop the xml, I cannot change the way the xml is sent to me. The xml is put on a queue, and the architecture does not allow for putting different xml's on different queues.....via contract with the third party vendor.
Any idea that I'm not seeing?
I don't like different xml's on the same queue............but that's ship has sailed.
The xml's below are made up........but show that the xml's are just completely different and share nothing.
<root>
<orders>
<order orderId="ABC123">
<orderDetails>
<orderDetail itemName="Bike" quantity="1"/>
<orderDetail itemName="TeddyBear" quantity="2"/>
<orderDetail itemName="Doll" quantity="3"/>
</orderDetails>
</order>
<!-- -->
<order orderId="DEF234">
<orderDetails>
<orderDetail itemName="Truck" quantity="4"/>
<orderDetail itemName="Marbles" quantity="5"/>
<orderDetail itemName="BoardGame" quantity="6"/>
</orderDetails>
</order>
</orders>
</root>
<root>
<employees>
<employee employeeSSN="222222222" firstName="John">
<employeeEmails>
<employeeEmail emailValue="john#home.com" />
<employeeEmail emailValue="john#work.com" />
</employeeEmails>
</employee>
<!-- -->
<employee employeeSSN="3333333" firstName="Mary">
<employeeEmails>
<employeeEmail emailValue="mary#home.com" />
<employeeEmail emailValue="mary#work.com" />
<employeeEmail emailValue="mary#spamcatcher.com" />
</employeeEmails>
</employee>
</employees>
</root>
Related
I have xml files which look like this:
<?xml version="1.0" encoding="utf-8"?>
<record id="177" restricted="false">
<type>record type</type>
<startdate>2000-10-10</startdate>
<enddate>2014-02-01</enddate>
<titles>
<title xml:lang="en" type="main">Main title</title>
<!-- only one title element with type main -->
<title xml:lang="de" type="official">German title</title>
<!-- can have more titles of type official -->
</titles>
<description>description of the record</description>
<categories>
<category id="122">
<name>category name</name>
<description>category description</description>
</category>
<!-- can have more categories -->
</categories>
<tags>
<tag id="5434">
<name>tag name</name>
<description>tag description</description>
</tag>
<!-- can have more tags -->
</tags>
</record>
How do I select the data from these xml files using LINQ, or should I use something else?
You can load xml into XDocument objects using either the Load() method
for files, or the Parse() method for strings:
var doc = XDocument.Load("your-file.xml");
// OR
var doc = XDocument.Parse(yourXmlString);
Then you can access the data using LINQ:
var titles =
from title in doc.XPathSelectElements("//title")
where title.Attribute("type").Value == "official"
select title.Value;
Was searching for examples of Xmlserializer and found this: How to Deserialize XML document
So why not to try. I did Ctrl+C and Edit -> Paste Special -> Paste XML As Classes in Visual Studio 2013 and... Whoa I got all the classes generated. One condition target framework must be 4.5 and this function is available from Visual Studio 2012+ (as stated in that post)
I have an XML file which contains employee details. How can i edit the existing employee names in that MXL file using C# .NET.
Here is the xml file.
<?xml version="1.0" encoding="utf-8"?>
<Employees>
<Employee id="1">
<Name>Employee 1</Name>
<Designation>SE </Designation>
<Qualification>MCA </Qualification>
</Employee>
<Employee id="2">
<Name>Employee 2</Name>
<Designation>SE </Designation>
<Qualification>MCA </Qualification>
</Employee>
<Employee id="3">
<Name>Employee 3</Name>
<Designation>SE </Designation>
<Qualification>MCA </Qualification>
</Employee>
</Employees>
How can i edit the employee names. I am new to xml. For example using Console Application
You can simple do that using Linq to Xml.
using System.Xml.Linq;
...
XDocument xDoc = XDocument.Load(#"Your xml file path goes here"); // or XDocument.Parse("Your xml string goes here");
xDoc.Root.Elements("Employee").First(xe => xe.Attribute("id").Value == "1").Element("Name").Value = "your value";
Here is a good reference for head start: Programming Guide (LINQ to XML)
you can use XML Serialization, in my opinion this is the most comfortable way
of working with c# and xml,
some examples are here:
http://msdn.microsoft.com/en-us/library/58a18dwa(v=vs.110).aspx
I feel I have done this many times, but it seems like I have to jump through too many hoops, and I am wondering if there is an easier way.
I am using WCF to build out an API (REST and SOAP endpoints). I am building out what I would like the XML response to look like from one of my calls, and I would like to know the easiest way to get its equivalent object model (Data Contracts).
here is a sample XML request where GetSectionInvitesResponse is the top level contract that should be returned from the API call.
<GetSectionInvitesResponse>
<UserID></UserID>
<OrganizationInvites>
<SectionInvites>
<SectionSubscriber>
<Section>
<ID></ID>
<Name></Name>
<Description></Description>
<Descriptor></Descriptor>
<ParentID></ParentID>
</Section>
<SectionSubscriberID>
</SectionSubscriber>
<SectionSubscriber>
<Section>
<ID></ID>
<Name></Name>
<Description></Description>
<Descriptor></Descriptor>
<ParentID></ParentID>
</Section>
<SectionSubscriberID>
</SectionSubscriber>
</SectionInvites>
</OrganizationInvites>
<OrganizationInvites>
<SectionInvites>
<SectionSubscriber>
<Section>
<ID></ID>
<Name></Name>
<Description></Description>
<Descriptor></Descriptor>
<ParentID></ParentID>
</Section>
<SectionSubscriberID>
</SectionSubscriber>
<SectionSubscriber>
<Section>
<ID></ID>
<Name></Name>
<Description></Description>
<Descriptor></Descriptor>
<ParentID></ParentID>
</Section>
<SectionSubscriberID>
</SectionSubscriber>
<SectionSubscriber>
<Section>
<ID></ID>
<Name></Name>
<Description></Description>
<Descriptor></Descriptor>
<ParentID></ParentID>
</Section>
<SectionSubscriberID>
</SectionSubscriber>
</SectionInvites>
</OrganizationInvites>
</GetSectionInvitesResponse>
EDIT
Because I was not clear enough in my initial post, I want to make more clear what I am aiming to gain from this question.
I want to know the best way to expose this over SOAP and REST with minimal duplicated code while following the same XML schema as shown above?
In theory you can:
Paste the sample xml into your favorte xml editor
Have the editor auto generate an xml schema for you. In Visual Studio its XML->Generate Schema. For example InvitesResponse.xsd.
From a command prompt run svcutil /dconly InvitesResponse.xsd /language:C# to create a DataContract file.
Out of curiosity I went through these steps and discovered:
<SectionSubscriberID> isn't closed correctly in your xml.
That the DataContractSerializer doesn't allow node sequences the way you currently have them defined.
svcutil output:
Error: Type 'GetSectionInvitesResponse' in namespace '' cannot be
imported. 'maxOccurs' on element 'OrganizationInvites' must be 1.
Either c hange the schema so that the types can map to data contract
types or use ImportXmlType or use a different serializer.
So I found the DataContract Schema Reference that points out that in a complex type must have maxOccurs = 1.
You will probably have to change your schema if you want to keep the DataContract serializer and not switch to the XmlSerializer... which you would also discover if you just started coding.
It is at this point that the wisdom of #John Sanders kicked in and I stopped.
I will need to be able to receive this xml data from a Java WebService and I am not really sure what to expose in my WebMethod so I can consume it? It is just a basic order and items. In .Net I would just have passed an order object List.
I should expand a bit further. It is an Oracle BPEL process that will need to map to this exposed C# WebService. I would need to expose the OrderNumber, ItemNumber ,etc (as shown in XML). The issue I am having is that I would have 1 to Many items ,etc so I can't just expose the basic items (string, int).
Probably pretty trivial for most the community here...just not sure how to do it? Any suggestions greatly appreciated.
I could do something like (build an order object and it appears to show the xml as I would expect?)
[WebMethod]
public static List<Orders> GetOrders(List<Orders> ordersList)
{
List<Orders oList = ordersList;
return oList;
}
XML:
<Order>
<OrderNumber>12345</OrderNumber>
<OrderDate>01/25/2010</OrderDate>
<OrderSource>Affiliate123</OrderSource>
<Items>
<ItemNumber>123478</ItemNumber>
<Qty>5</Qty>
<UOM>EA</UOM>
<Description>Test Item</Description>
</Items>
</Order>
You have answered your own question. The .NET web services framework will map a return type of List<T> to a sequence of T at the SOAP level, just as if you had used a T[] (array of T).
When I write up a quick sample service just like yours, this is the XML it returns:
<?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>
<GetOrdersResponse xmlns="http://tempuri.org/">
<GetOrdersResult>
<Order>
<OrderNumber>int</OrderNumber>
<OrderDate>dateTime</OrderDate>
<OrderSource>string</OrderSource>
<Items>
<Item xsi:nil="true" />
<Item xsi:nil="true" />
</Items>
</Order>
<Order>
<OrderNumber>int</OrderNumber>
<OrderDate>dateTime</OrderDate>
<OrderSource>string</OrderSource>
<Items>
<Item xsi:nil="true" />
<Item xsi:nil="true" />
</Items>
</Order>
</GetOrdersResult>
</GetOrdersResponse>
</soap:Body>
</soap:Envelope>
Your BPEL layer should be able to consume that pretty easily.
You don't need to expose a WebMethod, as I am assuming you are not publishing a WebService, instead you are consuming someone else's WebService.
I am not sure if I understand your question correctly, but if I do then in Visual Studio you just have to "Add Webreference" to the WebService URL and it should automatically create the .NET proxy objects, you can then use these objects to consume the methods.
Cheers,
Mithun
http://blog.mithunbose.com
I have an xml in which i have stored some html under comments like this
<root>
<node>
<!--
Mail me
-->
</node>
</root>
now in my Transform Xslt code of mine i am giving XPathNavigator which is pointing to node and in xslt i am passing the comment value of as a parameter.
assuming $href to be Mail me
in xslt i am doing <xsl:value-of select="$href" disable-output-escaping="yes">
but $href is still escaped the result of xslt transformation comes up with < >
Does any one know whats wrong with it any help in this regard would be highly appericiated.
Thanks
Regards
Azeem
When part of the comment the node looses its special meaning - thus "href" is not a node so you cannot use it to select stuff.
You can select comments like this:
<xsl:template match="/">
<xsl:value-of select="/root/node/comment()" disable-output-escaping="yes"/>
</xsl:template>
This will produce based on your XML input:
cristi:tmp diciu$ xsltproc test.xsl test.xml
<?xml version="1.0"?>
Mail me
As diciu mentioned, once commented the text inside is no longer XML-parsed.
One solution to this problem is to use a two-pass approach. One pass to take out the commented node and place it into normal XML, and a second pass to enrich the data with your desired output: Your Text Here.
A second, single-pass approach would be to extract the text you need from the comment (in this case the email address) via a regular expression (or in our case just pulling from the XML), and then create the markup needed around it.
<xsl:template match="ahrefmail/comment()">
<xsl:element name="a">
<xsl:attribute name="href" select="../../mail"/>
<xsl:attribute name="class" select="'text'"/>
<xsl:text>Mail Me!</xsl:text>
</xsl:element>
</xsl:template>
This assumes you already have an identity template in place
i did tried what u just said didn't worked the xml i am using is
<?xml version="1.0" ?>
<root>
<institution id="1">
<data>
<ahrefmail>
<!--
<a href='mailto:ibank#abibbankuk.com' class='text'></a>
-->
</ahrefmail>
<mail>
ibank#abibbankuk.com
</mail>
</data>
</institution>
<institution id="2">
<data>
<ahrefmail>
<!--
<a href='mailto:ibank#abibbankuk2.com' class='text'></a>
-->
</ahrefmail>
<mail>
ibank#abibbankuk2.com
</mail>
</data>
</institution>
</root>
in xslt i am doing
where $id is passed as parameter == 1
the ahrefmail node is still escaped with lt & gt
Thanks
Regards
Azeem