I am generating an XML file that I am sending to another system. The XML file generates correctly however the secondary system requires specific headers to deserialize correctly.
I am struggling with the XML tags and how to structure my classes that insert the data.
PostShipmentNotesBD -> ShipmentNoteBD -> Shipmentheader -> ShipmentDetailsBD -> MerchandiseLineBD
[XmlType("PostShipmentNotes")] -> [XmlType("ShipmentNote")] -> [XmlType("ShipmentHeader")] -> [XmlType("ShipmentDetails")] -> [XmlType("MerchandiseLine")]
For whatever reason the PostShipmentNotes and MerchandiseLines use the XMLType as the header but the rest do not? I have played around with roots, elements and more but I am a bit out of my area of knowledge and just looking for the right direction.
<?xml version="1.0" encoding="utf-8"?>
<PostShipmentNotes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ShipmentNoteBD>
<ShipmentHeader>
<CustomerName>Some Company</CustomerName>
<ShipmentStatusPrinted>Y</ShipmentStatusPrinted>
<ShipCode>1010</ShipCode>
<PlannedShipmentDate>2021-11-10</PlannedShipmentDate>
<SalesOrder>666777</SalesOrder>
<ShipAddress1>Big Long Street Name</ShipAddress1>
<ShipAddress2> </ShipAddress2>
</ShipmentHeader>
<ShipmentDetailsBD>
<MerchandiseLine>
<SalesOrderLine>1</SalesOrderLine>
<ShipmentQty>21</ShipmentQty>
<OverOrUnderShipment>N</OverOrUnderShipment>
</MerchandiseLine>
</ShipmentDetailsBD>
</ShipmentNoteBD>
</PostShipmentNotes>
Related
Simplified XML file I need to decode:
<?xml version="1.0" encoding="UTF-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:deliverylistResponse xmlns:ns2="http://tdriverap3.wsbeans.iseries/">
<return>
<COUNT>3</COUNT>
<DELIVERIES>
<ADD1>1300 address 1</ADD1>
<CITY>NICE CITY</CITY>
<ZIP>85705</ZIP>
</DELIVERIES>
<DELIVERIES>
<ADD1>40 S PINAL PKWY AVE</ADD1>
<CITY>FLORENCE</CITY>
<ZIP>85132</ZIP>
</DELIVERIES>
<DELIVERIES>
<ADD1>1825 EAST MAIN</ADD1>
<CITY>CHANDLER</CITY>
<ZIP>85286</ZIP>
</DELIVERIES>
<ERRORCODE/>
<RUNDATE>09/26/2018</RUNDATE>
</return>
</ns2:deliverylistResponse>
</soap:Body>
</soap:Envelope>
I am using the following to try and decode each of the individual addresses in the code.
I cannot figure out how to access them.
XElement xelement = XElement.Load(#"e:\test\X2.xml");
IEnumerable<XElement> addresses = xelement.Elements();
foreach (var address in addresses)
{
Console.WriteLine(address);
Console.WriteLine(address.Element("CITY").Value);
}
The first writeline works (it outputs the entire XML tree), the second says "System.Xml.Linq.XContainer.Element(...) returned null" - I have tried using DELIVERIES, COUNT, Body etc...
Obviously I am not telling it correctly how to traverse the structure, but I do not know how to go any further with it..
UPDATE: Thanks to some help I have figured out how to do it using Linq.
I would still like to be able to deserialize it if anybody has a pointer.
I followed several tutorials, but the multiple levels of this XML seems to be throwing me off.
I have created a class to hold the data but that is as far as my success with that path has gone.
Thank you,
Joe
Thank you Crowcoder -- this is what I wound up with, which will work.
The real XML file however does have about 60 fields so this is not as good as using a deserialize routine but I can at least move forward with the project.
XElement xelement = XElement.Load(#"e:\test\x2.xml");
IEnumerable<XElement> textSegs =
from seg in xelement.Descendants("DELIVERIES")
select seg;
foreach (var address in textSegs)
{
Console.WriteLine(address.Element("ADD1").Value);
Console.WriteLine(address.Element("CITY").Value);
Console.WriteLine(address.Element("ZIP").Value);
}
Console.ReadKey();
Thank you all for suggesting things and helping whenever in need.
Yesterday I was trying to develop and web app in asp.net 4.0 where I needed to parse the data from xml and save it in database. But before that I will also have to validate it.
I tried using .net provided tool xsd.exe to generate the schema file, but I dont know how will it know to mark which nodes or attributes are compulsory?
Like in my xml below items are mandatory
Root node <Market>
<Login> and its sub element
<ProductType> and its <ProductTypeID/>
The attribute DML is mandatory but should have only 3 values NONE, PUT or MODIFY
<ProductType> may or may not have <ProductItem>
If <ProductItem> is present then it should have <ProductItemID>
<ProductItem> may or may not have <Brand>
If <Brand> is present then it should have <BrandID>
Below is my xml
<?xml version="1.0" encoding="utf-8" ?>
<Market>
<Login>
<LoginId />
<Password />
</Login>
<ProductType DML="NONE">
<ProductTypeID/>
<Name/>
<Detail/>
<ProductItem DML="PUT">
<ProductItemID/>
<Name/>
<Detail/>
<Brand DML="PUT">
<BrandID/>
<Name/>
<Detail/>
</Brand>
<Brand DML="MODIFY">
<BrandID/>
<Name/>
<Detail/>
</Brand>
</ProductItem>
<ProductItem DML="MODIFY">
<ProductItemID/>
<Name/>
<Detail/>
</ProductItem>
</ProductType>
</Market>
How and where should I specify all the mandatory and optional parameters, so that my xsd is generated as per the requirement.
Thanks,
M.
xsd.exe can only try to infer, which elements/attributes are in you xml, but it cannot find out which information is mandatory. But this is a good startingpoint.
use a graphical XML_Schema_Editor to edit the genrated xsd to mark your mandatory fields. That is much easier than learning the xsd-language
I don't think XSD support nested XML. I would try to load the XML into an XmlDocument and check mandatory fields manually.
I'm trying to do very simple operations on a .cxml file. As you know it's basically an .xml file. This is a sample file I created to test the application:
<?xml version="1.0" encoding="utf-8"?>
<Collection xmlns:p="http://schemas.microsoft.com/livelabs/pivot/collection/2009" SchemaVersion="1.0" Name="Actresses" xmlns="http://schemas.microsoft.com/collection/metadata/2009">
<FacetCategories>
<FacetCategory Name="Nationality" Type="LongString" p:IsFilterVisible="true" p:IsWordWheelVisible="true" p:IsMetaDataVisible="true" />
</FacetCategories>
<!-- Other entries-->
<Items ImgBase="Actresses_files\go144bwo.0ao.xml" HrefBase="http://www.imdb.com/name/">
<Item Id="2" Img="#2" Name="Anna Karina" Href="nm0439344/">
<Description> She is a nice girl</Description>
<Facets>
<Facet Name="Nationality">
<LongString Value="Danish" />
</Facet>
</Facets>
</Item>
</Items>
<!-- Other entries-->
</Collection>
I can't get any functioning simple code like:
XDocument document = XDocument.Parse(e.Result);
foreach (XElement x in document.Descendants("Item"))
{
...
}
The test on a generic xml is working. The cxml file is correctly loaded in document.
While watching the expression:
document.Descendants("Item"), results
the answer is:
Empty "Enumeration yielded no results" string
Any hint on what can be the error? I've also add a quick look to get Descendants of Facet, Facets, etc., but there are no results in the enumeration. This obviously doesn't happen with a generic xml file I used for testing. It's a problem I have with .cxml.
Basically your XML defines a default namespace with the xmlns="http://schemas.microsoft.com/collection/metadata/2009" attribute:
That means you need to fully qualify your Descendants query e.g.:
XDocument document = XDocument.Parse(e.Result);
foreach (XElement x in document.Descendants("{http://schemas.microsoft.com/collection/metadata/2009}Item"))
{
...
}
If you remove the default namespace from the XML your code actually works as-is, but that is not the aim of the exercise.
See Metadata.CXML project under http://github.com/Zoomicon/Metadata.CXML sourcecode for LINQ-based parsing of CXML files.
Also see ClipFlair.Metadata project at http://github.com/Zoomicon/ClipFlair.Metadata for parsing one's CXML custom facets too
BTW, at http://ClipFlair.codeplex.com can checkout the ClipFlair.Gallery project for how to author ASP.net web-based forms to edit metadata fragments (parts of CXML files) and merge them together in a single one (that you then convert periodically to DeepZoom CXML with PAuthor tool from http://pauthor.codeplex.com).
If anyone is interested in doing nesting (hierarchy) of CXML collections see
http://github.com/Zoomicon/Trafilm.Metadata
and
http://github.com/Zoomicon/Trafilm.Gallery
I’m after some C# code that will have the following methods that will return Xml as the result.
Search the Apple iTunes App store. If I pass it a name or partial name the function must return a list of possible search results or just one result if it is a perfect match.
Example shown below:
<App>
<AppId>321564880</AppId>
<Name>Doodle Clock - Clock A Doodle Do!</Name>
<ReleaseDate>Released Sep 28, 2009</ReleaseDate>
<Artist>YARG</Artist>
<Description>Description of App</Description>
<Copyright>© YARG Limited 2009</Copyright>
<Price>$0.99</Price>
<Category>Lifestyle</Category>
<MainImageUrl><!—main App icon image urlà </ImageUrl>
<ExtraImages>
<!-- these will be the extra images you see in the App store other than the main application icon -->
<ImageUrl> <!—url of extra image 1à</ImageUrl>
<ImageUrl> <!—url of extra image 2à</ImageUrl>
<ImageUrl> <!—url of extra image 3à</ImageUrl>
</ExtraImages>
<Version>Version: 1.1 (iPhone OS 3.0 Tested)</Version>
<Size>1.5 MB</Size>
</App>
Okay the best way to create xml file and parse and manipulate them is using XDocument,XElement,etc. Because they are enumerable which means you can use LINQ on them and that will help you a lot.
For example :
XElement element = new XElement("Persons",
new XElement("Person","John",
new XAttribute("Id","1")),
new XElement("Person","Aaron",
new XAttribute("Id",2))
)
returns
<Persons>
<Person Id="1">John</Person>
<Person Id="2">Aaron</Person>
</Person>
More information : System.Xml.Linq Namespace
If you are looking for speed, then you can use XMLReader and XMLWriter but you can't find the flexibility that System.Xml.Linq provides.
You should use XPath in .NET:
http://www.aspfree.com/c/a/.NET/Working-with-XPath-The-NET-Way/
I would use XmlTextReader. It's the fastest way (though read-forward-only) - if you are maybe looking for speed. If not, XPath should do.
I have a set of configuration items I need to persist to a "human readable" file. These items are in a hierarchy:
Device 1
Name
Channel 1
Name
Size
...
Channel N
Name
...
Device M
Name
Channel 1
Each of these item could be stored in a Dictionary with a string Key and a value. They could also be in a structure/DTO.
I don't care about the format of the file as long as it's human readable. It could be XML or it could have something more like INI format
[Header]
Key=value
Key2=value
...
Is there a way to minimize the amount of boiler plate code I would need to write to manage storing/reading configuration items?
Should I just create Data Transfer Objects (DTO)/structures and mark them serializable (Does that generate bloated XML still human readable?)
Is there other suggestions?
Edit: Not that the software has to write as well as read the config. That leaves app.config out.
YAML for .NET
I think both the XmlSerializer and NetDataContractSerializer create human readable XML. I prefer the NetDataContractSerializer because it can do things the XmlSerializer cannot, but those extra features are probably more than you need for this. If you already have classes written for your configurations, one of these two are probably your shortest path to victory.
You could also write your configurations to the local app.config file, or a sub-config file using custom ConfigSections and the Configuration class.
If you serialize your structure to JSON you get a simpler representation of your object than in XML.
Here's a sample from James Netwon-King's JSON.Net site:
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string json = JavaScriptConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "Expiry": new Date(1230422400000),
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = JavaScriptConvert.DeserializeObject<Product>(json);
You can read his blog and download JSON.Net here.
See the FileHelpers library. It's got tons of stuff for reading from and writing to a lot of different formats - and all you have to do is mark up your objects with attributes and call Save(). Sort of like ORM for flat files.
I suspect that what you'll want to use is an app.config file which contains your settings in an XML format that .NET will be able to load in using the System.Configuration namesapce.
More info here: Link
I've generally used the registry for storing configurations (I know, bad me!), but using System.Xml to read/write a lightweight XML file isn't hard. In fact, I've done just that recently for a plugin project that uses XML documents to communicate with its host as well as store its own persistent settings.
There is also the System.Configuration namespace, but I've not really dealt with it.
I'd use a data structure that can be serialized into XML - in fact, since I'm lazy, I'd use an ADO.NET DataSet, since it has a simple serialization format that you can produce without having to think terribly hard.
As far as making it human-readable goes: if it just has to be human-readable (and not human-modifiable, which I think is what you're describing here), I'd build an XSLT transform and use it to produce an HTML version of the configuration data whenever I wrote out the XML. That gives you as fine-grained control over the visual presentation of the data as you could possibly ask for.
My preference in this situation is to create a DataSet with DataTables for the configuration data arranged in a nice relational way - then use DataSet.WriteXML() to save it to a configuration file.
Then to load it again, you just use DataSet.ReadXML() and it's back in a nice query-able object.
This is an example config file that my app allows the user to edit in a Text Editor window:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<!--****************************************************************
Config File: FileToExcel_test.cfg
Author: Ron Savage
Date: 06/20/2008
Description:
File to test parsing a file into an Excel workbook.
Modification History:
Date Init Comment
06/20/2008 RS Created.
******************************************************************-->
<!--********************************************************************
Global Key Definitions
********************************************************************-->
<config key="sqlTimeout" value="1800"/>
<config key="emailSMTPServer" value="smtp-server.austin.rr.com"/>
<config key="LogFile" value="FiletoExcel_test_{yyyy}{mm}{hh}.log"/>
<config key="MaxEntries" value="1"/>
<!--********************************************************************
Delimiter Configurations
********************************************************************-->
<config key="pipe" value="|"/>
<!--********************************************************************
Source / Target Entries
********************************************************************-->
<config key="source_1" value="FILE, c:\inetpub\ftproot\filetoexcel.txt, pipe, , , , , "/>
<config key="target_1" value="XLS, REPLACE, c:\inetpub\ftproot\filetoexcel1.xls, , , , , , , ,c:\inetpub\ftproot\filetoexcel_template.xls, ,3"/>
<config key="notify_1" value="store_error, store_success"/>
</configuration>
When I load it into the DataSet, all the non-comment tags reside in a table named Config with fields Key & value. Very easy to search.