Deserialize with XmlSerializer having external xmlns reference - c#

I have an ever increasing number of BCP (t-sql) format files in XML that I need to read. I create the xsd file using xsd.exe and a number of BCP format files and attempt to read the xml file as an object. But it fails like this:
Unhandled Exception: System.InvalidOperationException: There is an error in XMLdocument (4, 6). ---> System.InvalidOperationException: The specified type was not recognized: name='CharTerm', namespace='http://schemas.microsoft.com/sqlserver/2004/bulkload/format', at .
The XML file is like this:
<?xml version="1.0" encoding="utf-8" ?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="32"/>
<FIELD ID="2" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="4"/>
<FIELD ID="3" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="4"/>
<FIELD ID="4" xsi:type="CharTerm" TERMINATOR=";" MAX_LENGTH="20"/>
<FIELD ID="5" xsi:type="CharTerm" TERMINATOR="\r\n" MAX_LENGTH="16"/>
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="col1" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="2" NAME="col2" xsi:type="SQLINT"/>
<COLUMN SOURCE="3" NAME="col3" xsi:type="SQLINT"/>
<COLUMN SOURCE="4" NAME="col4" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="5" NAME="col5" xsi:type="SQLFLT4"/>
</ROW>
</BCPFORMAT>
I read the XML file like this:
FileStream fs = File.OpenRead(formatFileName);
XmlSerializer serializer = new XmlSerializer(typeof(FormatSchemasXml.BCPFORMAT));
FormatSchemasXml.BCPFORMAT bcp_format = (FormatSchemasXml.BCPFORMAT)serializer.Deserialize(fs);
fs.Close();
The external xmlns reference does not seem to be used. I have searched a lot of documentation, but failed at seeing how I can fix this. Preferably without having to modify the BCP XML format files (I'd like to use them as is).
Suggestions?

Related

How to insert an XML File into Another XML File at Specific Node C#

I have two XML Files ,the first one is and Named as XMLTemplate
<DataSources>
<DataSource Name="XXXX">
</DataSource>
<DataSource Name="ABC">
</DataSource>
</DataSources>
<DataSets>
<DataSet Name="abc">
<Query>
</Query>
<ReportSections>
</ReportSections>
and the second xml file is named as XMLGenrated,
<Fields>
<Field >
</Field>
</Fields>
and I need the Output as,
<DataSource Name="XXXX">
</DataSource>
<DataSource Name="ABC">
</DataSource>
</DataSources>
<DataSets>
<DataSet Name="abc">
<Query>
<Fields>
<Field >
</Field>
</Fields>
</Query>
<ReportSections>
</ReportSections>
Both the Files are in .XML Extension and I dont know how to find the node by its Name Can anyone help me out.
I tried this,
XElement xFileRoot = XElement.Load(XMLTemplate.xml);
XElement xFileChild = XElement.Load(XMLGenerated.xml);
xFileRoot.Add(xFileChild);
xFileRoot.Save(file1.xml);
but the XML adds below the XMLTemplate I dont know how to insert at particular node.
Find the node using Linq to XML and Replace its contents
XElement xFileRoot = XElement.Load(XMLTemplate.xml);
XElement xFileChild = XElement.Load(XMLGenerated.xml);
var queryNode = xFileRoot.Element("Query");
queryNode.ReplaceWith(xFileChild) ;
Based on on this answer - How can I update/replace an element of an XElement from a string?
Be aware that you sample XML files contain multiple root nodes, and that if you need to keep the <Query> node you need to change this.

SQL Server bulk insert XML format file with Maximum LENGTH

I want to set the length to MAX for one of my XML fields.
XML Code:
<?xml version="1.0"?>
<BCPFORMAT xmlns="http://schemas.microsoft.com/sqlserver/2004/bulkload/format" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<RECORD>
<FIELD ID="1" xsi:type="CharFixed" LENGTH="3" />
<FIELD ID="2" xsi:type="CharFixed" LENGTH="MAXLENGTH" />
<FIELD ID="3" xsi:type="CharFixed" LENGTH="10" />
<FIELD ID="4" xsi:type="CharFixed" LENGTH="8" />
</RECORD>
<ROW>
<COLUMN SOURCE="1" NAME="Field1" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="2" NAME="Field2" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="3" NAME="Field3" xsi:type="SQLNVARCHAR"/>
<COLUMN SOURCE="4" NAME="Field4" xsi:type="SQLNVARCHAR"/>
</ROW>
</BCPFORMAT>
But 'MAXLENGTH' does not seem to work.
Error message:
bad value MAXLENGTH for attribute "LENGTH"
Any suggestions on how to put the LENGTH to maximum ?
The length of a string is limited to 4000 (nchar) or 8000 (char) type. There is no max length-constant - AFAIC
Refer to this, "Field Attributes"
If you look up the schema meta-data just as SQL Server does, you can follow this link
http://schemas.microsoft.com/sqlserver/2004/bulkload/format/bulkloadschema.xsd
to find this
<xsd:attribute name="LENGTH" type="xsd:positiveInteger" use="required"/>
[...]
<xsd:attribute name="MAX_LENGTH" type="xsd:positiveInteger" use="optional"/>
So the length is required while max_length seems to be optional, but if you specify it, it must be a positive integer.

How to use LINQ to get data from an XML file?

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)

XML to LINQ with metadata

I'm very new to both XML and LINQ. I've read several XML to LINQ tutorials, but none of the XML documents seem to be formatted the way mine is. I'm not sure if (and how) it changes things.
All the examples I've read on the internet seem to follow this format:
<data>
<row>
<Term>201320</Term>
<Subj>ACCT</Subj>
<Subj_desc>Accounting</Subj_desc>
</row>
<row>
<Term>201320</Term>
<Subj>ACCT</Subj>
<Subj_desc>Accounting</Subj_desc>
</row>
</data>
If I wanted to read that I think the code would look something like this:
XDocument document = XDocument.Load("URLHERE.xml");
var term = from row in document.Descendants("row")
select new
{
Term = row.Element("Term").Value,
Subject = row.Element("Subj").Value,
Subject_Description = row.Element("Subj_desc").Value,
};
Here's the problem: my XML document doesn't follow the same format. Instead of repeating the different tags for each term, it has a set of metadata at the top and then uses the SAME tag for each set of data.
Here's a sample of my XML document:
<metadata>
<item name="TERM" type="xs:string" length="128"/>
<item name="SUBJ" type="xs:string" length="128"/>
<item name="SUBJECT_DESC" type="xs:string" length="512"/>
</metadata>
<data>
<row>
<value>201320</value>
<value>ACCT</value>
<value>Accounting</value>
</row>
<row>
<value>201320</value>
<value>ACCT</value>
<value>Accounting</value>
</row>
</data>
How would I extract data from it?
var term = from row in document.Descendants("row")
select new
{
Term = row.Element("value").Value,
Subject = row.Element("value").Value,
};
Doesn't seem right. I'm using C# BTW (not sure if I need to say that or if the tag's sufficient).
Your XML is not properly formatted, you need a root element that encapsulates the entire document. such as
<?xml version='1.0' encoding='utf-8'?>
<root>
<metadata>
<item name="TERM" type="xs:string" length="128"/>
<item name="SUBJ" type="xs:string" length="128"/>
<item name="SUBJECT_DESC" type="xs:string" length="512"/>
</metadata>
<data>
<row>
<value>201320</value>
<value>ACCT</value>
<value>Accounting</value>
</row>
<row>
<value>201320</value>
<value>ACCT</value>
<value>Accounting</value>
</row>
</data>
</root>
Then using XDocument you could load the file
var doc = XDocument.Load("file.xml");
then you can extract the data, kinda depends what you want to extract, you never specified. example of getting the metadata
var item = doc.Descendants("metadata");
getting rows, containing an IEnumerable of values
XDocument document = XDocument.Load("c:\\tmp\\test.xml");
var rows = from i in document.Descendants("row")
select new {values = i.Elements("value").Select(a=>a.Value)};

How I can read and excute a big xml file?

my code gives me error : "'.', hexadecimal value 0x00, is an invalid character. Line 2, position 1."
string FileName = "20110606 100419 ServerForShop 1.xml";
string root = Server.MapPath("~/Include/Xml Files/Patch/");
var custs = from c in XElement.Load(root + FileName).Elements("Update")
select c;
I want to read and execute command a big xml file it is about 350MB how I can read it ? here is my xml file structure :
<?xml version="1.0" encoding="utf-8"?>
<Update>
<Object Name="Good">
<Insert Table="Good">
<Field Name="GoodCode" Value="1" Type="Integer" />
<Field Name="GoodUserCode" Value="" Type="String" />
.
.
.
</Insert>
</Object>
</Update>
I would recommend looking here for some samples http://support.microsoft.com/kb/307548
and perhaps here How does one parse XML files?

Categories

Resources