views:

3406

answers:

4

I know its kind non sportiness asking for this kind of help, But I am relay stacked on this for while, Temporally I am reading two C# books and working everyday over 9 hours.

Okay here is my problem I have WIN C# application that I almost done. In SQL i got a three tables look like this:

CREATE TABLE [dbo].[Racuni](
[BROJ] [varchar](12) NULL,
[DATUM] [datetime] NULL,
[TS] [datetime] NULL,
[USER_ID] [int] NULL,
[KASA_ID] [varchar](3) NULL,
[TOTAL] [float] NULL,
[STATUS] [varchar](1) NULL,
[ARH] [varchar](max) NULL
 ) ON [PRIMARY]

Create Table "Rac_Npl" 
( br_rac Char( 12 )
, kasa_id Char( 3 )
, npl_id Integer
, iznos Money);

CREATE TABLE [dbo].[Stavke](
[br_rac] [varchar](12) NULL,
[kasa_id] [char](3) NULL,
[art_id] [int] NULL,
[kol] [float] NULL,
[mpc] [money] NULL,
[ompc] [money] NULL)

And I have XML file(s) on local disk for importing in that three tables Xml looks like this.

<?xml version="1.0" encoding="windows-1250"?>
<transaction>
<table name="qryRacuniSmjene">
<fields>
<field name="BROJ" type="1" size="12"/>
<field name="DATUM" type="9" size="0"/>
<field name="TS" type="11" size="0"/>
<field name="USER_ID" type="3" size="0"/>
<field name="KASA_ID" type="1" size="3"/>
<field name="TOTAL" type="8" size="4"/>
<field name="STATUS" type="1" size="1"/>
<field name="ARH" type="16" size="1"/>
</fields>
<data>
<row>
<![CDATA[09-0002-0001]]>
<![CDATA[16.04.2009]]>
<![CDATA[16.04.2009 13:23:27]]>
<![CDATA[1]]>
<![CDATA[001]]>
<![CDATA[2,60]]>
<![CDATA[D]]>
<![CDATA[
   porezni broj: 000000000000
   Zaobilaznica bb
]]>
</row>
<row>
<![CDATA[09-0002-0002]]>
<![CDATA[16.04.2009]]>
<![CDATA[16.04.2009 13:23:27]]>
<![CDATA[1]]>
<![CDATA[001]]>
<![CDATA[2,60]]>
<![CDATA[D]]>
<![CDATA[
   porezni broj: 000000000001
   Zaobilaznica bb
]]>
</row>
</data>
</table>
<table name="qryRac_nplSmjene">
<fields>
<field name="br_rac" type="1" size="12"/>
<field name="kasa_id" type="1" size="3"/>
<field name="npl_id" type="3" size="0"/>
<field name="iznos" type="8" size="4"/>
</fields>
<data>
<row>
<![CDATA[09-0002-0001]]>
<![CDATA[001]]>
<![CDATA[1]]>
<![CDATA[2,60]]>
</row>
<row>
<![CDATA[09-0002-0002]]>
<![CDATA[001]]>
<![CDATA[1]]>
<![CDATA[2,60]]>
</row>
</data>
</table>
<table name="qryStavkeSmjene">
<fields>
<field name="br_rac" type="1" size="12"/>
<field name="kasa_id" type="1" size="3"/>
<field name="art_id" type="3" size="0"/>
<field name="kol" type="6" size="0"/>
<field name="mpc" type="8" size="4"/>
<field name="ompc" type="8" size="4"/>
</fields>
<data>
<row>
<![CDATA[09-0002-0001]]>
<![CDATA[001]]>
<![CDATA[152414]]>
<![CDATA[1,000]]>
<![CDATA[2,60]]>
<![CDATA[2,60]]>
</row>
<row>
<![CDATA[09-0002-0001]]>
<![CDATA[001]]>
<![CDATA[152414]]>
<![CDATA[1,000]]>
<![CDATA[2,60]]>
<![CDATA[2,60]]>
</row>
</data>
</table>
</transaction>

Once again I am shamed because asking help on this way, But Ill try to suport StacOverFlow in any kind a way. Thanx in advice Best regards. Admir

A: 

You can use an XPathNavigator object to parse the XML, and then use an SqlCommand object to insert the data into the tables. There are lots of code samples for both objects on the Internet.

John M Gant
+2  A: 

Multiple CDATA elements are not consistantly supported across implementations. For example, you will have problems accessing them an XDocument or via SelectNodes. If you can change the input format that would make things easier.

This code hasn't been tested and there's no error handling or bad data checking, but it should get you started. Investigate using XPathDocument / XPathNavigator for performance and read my inline comments.

class XmlCsvImport
{
    public void ImportData(string xmlData, ConnectionStringSettings connectionSettings)
    {
        DbProviderFactory providerFactory = DbProviderFactories.GetFactory(connectionSettings.ProviderName);

        IDbConnection connection = providerFactory.CreateConnection();
        connection.ConnectionString = connectionSettings.ConnectionString;

        // TODO: Begin transaction

        XmlDocument doc = new XmlDocument();
        doc.LoadXml(xmlData);

        foreach (XmlNode tableNode in doc.SelectNodes("/transaction/table"))
        {
            IDbCommand command = CreatCommand(connection, tableNode);

            foreach (XmlNode rowNode in tableNode.SelectNodes("data/row"))
            {
                string[] values = GetRowValues(rowNode);

                if (values.Length != command.Parameters.Count)
                {
                    // TODO: Log bad row
                    continue;
                }

                this.FillCommand(command, values);
                command.ExecuteNonQuery();
            }
        }

        // TODO: Commit transaction
    }

    private IDbCommand CreatCommand(IDbConnection connection, XmlNode tableNode)
    {
        string tableName = tableNode.Attributes["name"].Value;

        IDbCommand command = connection.CreateCommand();
        command.Connection = connection;
        command.CommandType = CommandType.Text;

        XmlNodeList fieldNodes = tableNode.SelectNodes("fields/field");

        List<string> fieldNameList = new List<string>(fieldNodes.Count);

        foreach (XmlNode fieldNode in tableNode.SelectNodes("fields/field"))
        {
            string fieldName = fieldNode.Attributes["name"].Value;
            int fieldType = Int32.Parse(fieldNode.Attributes["type"].Value);
            int fieldSize = Int32.Parse(fieldNode.Attributes["size"].Value);

            IDbDataParameter param = command.CreateParameter();
            param.ParameterName = String.Concat("@", fieldNode.Attributes["name"]);
            param.Size = fieldSize;
            param.DbType = (DbType)fieldType; // NOTE: this may not be so easy
            command.Parameters.Add(param);

            fieldNameList.Add(fieldName);
        }

        string[] fieldNames = fieldNameList.ToArray();

        StringBuilder commandBuilder = new StringBuilder();
        commandBuilder.AppendFormat("INSERT INTO [{0}] (", tableName);

        string columnNames = String.Join("], [", fieldNames);
        string paramNames = String.Join(", @", fieldNames);

        command.CommandText = String.Concat(
            "INSERT INTO [", tableName, "] ([",
            columnNames,
            "]) VALUES (@",
            paramNames,
            ")"
            );

        return command;
    }

    private string[] GetRowValues(XmlNode row)
    {
        List<string> values = new List<string>();

        foreach (XmlNode child in row.ChildNodes)
        {
            if (child.NodeType == XmlNodeType.Text ||
                child.NodeType == XmlNodeType.CDATA)
            {
                values.Add(child.Value);
            }
        }

        return values.ToArray();
    }

    private void FillCommand(IDbCommand command, string[] values)
    {
        for (int i = 0; i < values.Length; i++)
        {
            IDbDataParameter param = (IDbDataParameter)command.Parameters[i];
            param.Value = values[i]; // TODO: Convert to correct data type
        }
    }
Richard Szalay
+1  A: 

I have this URL where there is XML data. I have to extract that data from URL and dump it into DW table. I am using SSIS Script Task for that.

This is how the data looks like:

-<currency>

 <csymbol>AED</csymbol>

 <cname>United Arab Emirates Dirhams</cname>

 <crate>3.6732001305</crate>

 <cinverse>0.2722421770</cinverse>

</currency>

−<currency>

 <csymbol>AFN</csymbol>

 <cname>Afghanistan Afghanis</cname>

 <crate>44.0000000000</crate>

 <cinverse>0.0227272727</cinverse>

</currency>

−<currency>

 <csymbol>ALL</csymbol>

 <cname>Albania Leke</cname>

 <crate>104.4100000001</crate>

 <cinverse>0.0095776267</cinverse>

</currency>

This is the code i'm using to load it into some Object type or something. But i dont know how to do that.

 public void Main()
    {
        String URLString = "http://www.xe.com/dfs/datafeed2.cgi?beeline";
        XmlDocument doc = new XmlDocument();
        XmlTextReader reader = new XmlTextReader(URLString);
        doc.Load(reader);

        XmlNodeList currencynodes = doc.SelectNodes("currency");
        foreach(XmlNode currency in currencynodes)
        {
            XmlNode csymbol = currency.SelectSingleNode("csymbol");
            string csymbolvalue = csymbol.Value;

            XmlNode cname = currency.SelectSingleNode("cname");
            string cnamevalue = cname.Value;

            XmlNode crate = currency.SelectSingleNode("crate");
            string cratevalue = crate.Value;

            XmlNode cinverse = currency.SelectSingleNode("cinverse");
            string cinversevalue = cinverse.Value;

            Dts.Variables["User::oCurrencyConversion"].Value = csymbol.Value;
        }
jack
A: 

Thanks John for the reply. Actually I am not good with Scripting in c#. I tried finding the samples but dint find any link which i can relate my issue to. Based on a few articles, i came up with the code above which took me like 2 days :)

It'll be really helpful if you can provide few lines which i can start off of.

I thought of posting a new question instead of using as an answer. You can use the link below.

http://stackoverflow.com/questions/3754297/writing-xml-data-from-url-to-object-in-ss-script-task

Thanks again

jack