Create SQL db structure from xpath - c#

I am trying to dump the contents of an xml file in to a sql table (relational format).
In the past, I have used dataset.readxml but have had some issues with it while handling many to many relationships.
So I took an approach as follows, create a unique list of xpath expression for all the elements and attributes in the xml file and then using these expressions create a sql db structure to persist this data.
I wanted to create this feature as a dynamic implementation to handle any xml.
Let's say I have an xml file and the unique Xpath are as follows
/movie/MovieId[1]
/movie/MovieName[1]
/movie/cast[1]
/movie/cast[1]/name[1]
/movie/cast[1]/name[2]
/movie/cast[1]/name[3]/#rolename
/movie/description[1]
/movie/directors[1]
/movie/directors[1]/name[1]
/movie/directors[1]/name[1]
/movie/directors[1]/name[2]
/movie/directors[1]/name[3]
/movie/releasedate[1]
/movie/releasedate[1]/#reldatetestatt
/movie/runtime[1]
I would like the table structure to be created as follows:
TableName: Movie
Columns: MovieId, MovieName, description, releasedate, reldatetestatt, runtime
TableName: Cast
Columns: MovieId, name, rolename
TableName: Directors
Columns: MovieId, name
Sample Xml for your reference:
var xml = #"<movies>
<movie>
<MovieId>277345</MovieId>
<MovieName>The Life and Passion of Jesus Christ</MovieName>
<description>The Gospels of the New Testament.</description>
<runtime>44</runtime>
<releasedate reldatetestatt='testattribute'>3/26/1904 12:00:00 AM</releasedate>
<directors>
<name>Lucien Nonguet</name>
<name>Ferdinand Zecca</name>
<name>Ferdinand Zecca 2</name>
</directors>
<cast>
<name rolename='test'>Madame Moreau</name>
<name>Monsieur Moreau</name>
</cast>
</movie>
</movies>";

You could try Talend Open Studio (aka Jaster ETL). It will happily take xml and fill a database. You can do it from the UI or export the "job" as independent java code.

Related

How to import XML into a SQL Server database with C# which has parents

I have approximately 100.000 xml files that each contain 1 row of data (but it has 2 parents).
What is the best way to read these XML files, and write the data to a SQL Server table ?
This is my XML:
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<recording>
<dataformat>audio</dataformat>
<starttime>2015-02-09 08:57:08:000 +0200</starttime>
<endtime>2015-02-09 08:58:48:000 +0200</endtime>
<nostart>false</nostart>
<noend>false</noend>
<recordingtype>stnbulk</recordingtype>
<recordingline></recordingline>
<servicename>005379763634</servicename>
<servicenumber></servicenumber>
<deliberatebreak>0</deliberatebreak>
<calldirection>Outgoing</calldirection>
<filename>890001000000003.wav</filename>
<otherinum>0</otherinum>
<callparty>1</callparty>
<recordingowners>
<recordingowner>131</recordingowner>
</recordingowners>
<parties>
<party id="1">
<number>131</number>
<name>Santral131</name>
<pstarttime>2015-02-09 08:58:48:912 +0200</pstarttime>
<pendtime>2015-02-09 08:58:48:912 +0200</pendtime>
</party>
<party id="2">
<number>005379763634</number>
<pstarttime>2015-02-09 08:58:48:912 +0200</pstarttime>
<pendtime>2015-02-09 08:58:48:912 +0200</pendtime>
</party>
</parties>
<guids>
</guids>
</recording>
I tried to read this data by using a XmlReader to a Dataset for insert to SQL Server database, but it didn't work.
Thanks in advance for your support.
Is this a one-time-action? Are the file names easy to list? Does the file's name carry any information? Are all 100k files identically structured?
Please provide the target structure of your tables.
On the first sight, the easiest was to write a stored procedure, accepting a paramter of type XML.
Your C# application uses XmlDocument to read the XML directly from file path and then passes the OuterXml to the SP. This SP will read the XML and insert its values into the target tables. Pass this just as string and do not pass the declaration <?xml ...?>. C# uses unicode implicitly and so does T-SQL-XML...
The following code will give you templates for each type of element how to read it. It should be easy to use something like this within your SP (where #xml is the passed in parameter).
Attention: However this XML was generated, the contained date-time values do not fullfill the appropriate format (ISO8601). This needs some tricksing...
Try this within a T-SQL SP:
DECLARE #xml XML=
'<recording>
<dataformat>audio</dataformat>
<starttime>2015-02-09 08:57:08:000 +0200</starttime>
<endtime>2015-02-09 08:58:48:000 +0200</endtime>
<nostart>false</nostart>
<noend>false</noend>
<recordingtype>stnbulk</recordingtype>
<recordingline></recordingline>
<servicename>005379763634</servicename>
<servicenumber></servicenumber>
<deliberatebreak>0</deliberatebreak>
<calldirection>Outgoing</calldirection>
<filename>890001000000003.wav</filename>
<otherinum>0</otherinum>
<callparty>1</callparty>
<recordingowners>
<recordingowner>131</recordingowner>
</recordingowners>
<parties>
<party id="1">
<number>131</number>
<name>Santral131</name>
<pstarttime>2015-02-09 08:58:48:912 +0200</pstarttime>
<pendtime>2015-02-09 08:58:48:912 +0200</pendtime>
</party>
<party id="2">
<number>005379763634</number>
<pstarttime>2015-02-09 08:58:48:912 +0200</pstarttime>
<pendtime>2015-02-09 08:58:48:912 +0200</pendtime>
</party>
</parties>
<guids>
</guids>
</recording>';
--This is the actual query
--INSERT INTO YourTargetTable(col1,col2,col3...)
SELECT r.value('(dataformat/text())[1]','nvarchar(max)') AS dataformat
,CONVERT(DATETIMEOFFSET,STUFF(STUFF(STUFF(STUFF(r.value('(starttime/text())[1]','nvarchar(max)'),11,1,'T'),20,1,'.'),24,1,''),27,0,':'),127) AS starttime
,r.value('(nostart/text())[1]','bit') AS nostart
--more columns
,r.value('(recordingowners/recordingowner/text())[1]','bit') AS recordingowner --if there might be more than one, this would need one more call to .nodes()
,p.value('#id','int') AS party_id
,p.value('(number/text())[1]','nvarchar(max)') AS party_number
--more columns
FROM #xml.nodes('/recording') AS A(r)
OUTER APPLY A.r.nodes('parties/party') AS B(p)
The (partial) result
audio 2015-02-09 08:57:08.0000000 +02:00 0 1 1 131
audio 2015-02-09 08:57:08.0000000 +02:00 0 1 2 005379763634
Hint: If you don't need the time zone, you might use this trick to implicitly add the timezone to the datetime...
DECLARE #dtZ DATETIMEOFFSET=CONVERT(DATETIMEOFFSET,'2015-02-09T08:58:48.912+02:00',127);
SELECT (SELECT #dtZ FOR XML PATH(''),TYPE).value('.','datetime');
The result has got the hour 6 now...
2015-02-09 06:58:48.913
Some background: The ISO8601 format would look like this
2015-02-09T08:58:48.9120000+02:00
If the strings within the XML were correctly formatted, the reading was done just as easy as any other value. My code uses multiple STUFF() calls to correct the format to make it convertible...

.NET MVC c# - model properties according xml

I have string in xml format with database table name and column description (like column name and data type) and I need to use it for create model(which will map the table) or modify model according the string at runtime. What is the best solution to do this?
When application is running, I need to access some table, with some columns, that can be changed in time, so i need to adapt model for this table.
Please recommend me the technique via I can reach the working solution. Thanks
My data:
I have this in string var:
<xml>
<col>
<name>OS</name>
<type>string</format>
</col>
<col>
<name>Name</name>
<type>string</format>
</col>
<col>
<name>Number</name>
<type>int</format>
</col>
</xml>
This xml string I obtain after some user action. So, I need to use it for access to table in .NET MVC. I use NHibernate, so I need to have model which map the table(name of the table is contained in my xml string) and then add NHibernate mapping for this model, I think. But I don't know, how to do it by some "clear" way

How to save xml data from an XmlDocument object into a SQL table using C#

my XML is as below
<employees>
<employee email="email1" dateofbirth="1900-01-01" lastname="lastname1" firstname="firstname1" />
<employee email="email2" dateofbirth="0001-01-01" lastname="lastname2" middleinitial="2" firstname="firstname2" />
</employees>
And my table [dbo.Employee] in the DB has the columns below
FirstName
LastName
DOB
The above XML data is available to me in an XmlDocument object. I would like to save the above data in the respective columns in the SQL table. Please help..
There are multiple options to upload XML file to SQL SERVER table.
1) You can use C# and SQL SERVER to achieve the same. Check this URL: http://www.aspdotnet-suresh.com/2012/12/aspnet-send-xml-file-as-parameter-to.html
2) Bulk insert functionality of SQL SERVER. Check this URL: http://msdn.microsoft.com/en-IN/library/ms191184.aspx
3) Using Data flow task or SSIS. Check this URL: How to load an XML file into a database using an SSIS package?
I had the same problem with you over the past week. What I ended up doing is using Python's pyodbc SQL connector to connect to the database and xml parser to parse the text from an xml file.
I believe you can do exactly the same using C#.
Here you can find out about the XML parser in C#.
Then you can connect to the database the way it is described in this link.
So, what you will end up doing, is iterating through the xml, using xml parser and then constructing the correct sql statement for inserting into the database.
In your example, the desired SQL code should look something like this:
INSERT INTO Employee (FirstName,LastName,DOB)
VALUES ('firstname1','firstname2','1900-01-01')
where the values inside quotes will be produced dynamically through the XML parser.

Retrieving metadata from xml files

I need to retrieve metadata from multiple xml files. The structure of the xml file is the following:
<songs>
<song_title> some title </song_title>
<classification> some classification </classification>
<song_text> some text </song_text>
<singer>
<sing> singer's name </sing>
<gender> gender </gender>
<bornYear> year </bornYear>
<livePlace> live place </livePlace>
<liveArea> live area </liveArea>
</singer>
</songs>
The user chooses the search criteria - live place or live area. Then he enters the name of the place or area, that he searches for. I need to find and display links to songs, which have in its metadata the place or area, that user has entered. I am using .NET 3.5
This answer is more of a pointer...
You can use LINQ to XML to accomplish this task.
What Is LINQ to XML?
LINQ to XML is a LINQ-enabled,
in-memory XML programming interface
that enables you to work with XML from
within the .NET Framework programming
languages.
LINQ to XML is like the Document
Object Model (DOM) in that it brings
the XML document into memory. You can
query and modify the document, and
after you modify it you can save it to
a file or serialize it and send it
over the Internet. However, LINQ to
XML differs from DOM: It provides a
new object model that is lighter
weight and easier to work with, and
that takes advantage of language
improvements in Visual C# 2008.
You can then search and manipulate any XML document element using LINQ query expressions like the following example:
IEnumerable<XElement> partNos =
from item in purchaseOrder.Descendants("Item")
where (int) item.Element("Quantity") *
(decimal) item.Element("USPrice") > 100
orderby (string)item.Element("PartNumber")
select item;
You can use XPathing to easily get whatever you want if you have an aversion to Linq
http://msdn.microsoft.com/en-us/library/ms256086%28VS.85%29.aspx
node.SelectNodes("Songs[/Singer/LivePlace='California']")
this would get all Songs nodes that have a singer node with a liveplace node with the value of California.

mapping (different)XML(formats) to a database table

how can i map xml file(s) of different formats to a table in my database say for example i have a table called Person
FirstName nvarchar(50),
LastName nvarchar(50),
Address nvarchar(500)
i have to map xml files submitted by users to the fields of Person, the xml files can be in different formats say for example one user submits in the following format
<Person>
<Names>
<FirstName>john</FirstName>
<LastName>smith</LastName>
</Names>
<Names>
<FirstName>john</FirstName>
<LastName>smith</LastName>
</Names>
</Person>
and another user submits it in the following format
<Person>
<PersonalInfo>
<Names>
<FirstName>john</FirstName>
<LastName>smith</LastName>
</Names>
.
.
.
<PersonalInfo>
</Person>
how can i device a solution that will handle different cases (different xml formats), so that if a user submits a xml file in whatever format i just have to tell the format to my aplication and its values will automatically gets mapped to the said table... im using visual studio 2010 as an IDE and C#.NET, i hope have narrated the problem well enough...
please advice...
Since I don't how dynamic this should be (meaning how often you will change the mappings) or how many different XMLs do u have I will suggest you to map the table(s) to a common class using your preferred ORM and create class instances using LinqToXml (which is very easy). One method or class per XML structure.
There is a sample here for the LinqToXml -> http://www.switchonthecode.com/tutorials/introduction-to-linq-simple-xml-parsing
Also, if you donĀ“t want to use it and are using .NET 4 I created a simple library to produce dynamic objects from a XML string. You can take a look at it here -> https://github.com/tucaz/XmlToObjectParser
you can identify the schema you are acquiring and use appropriate XSLT File to convert it to the latest version.
Note: you should make something generic to identify the schema (e.g. )
(I Like 1. better) create an Software Adapter interface that changes the mappings (Like add-ins work)

Categories

Resources