Native c# functions to desirabilia an xml - c#

I have a string like:
<Cols><Col idx="C1" Name="Speed" Type="Int" /><Col idx="C2" Name="Time" Type="Decimal" /></Cols>
that I need to convert to an XDocument:
the resulting xml is:
<Cols>
<Col idx="C1" Name="Speed" Type="Int" />
<Col idx="C2" Name="Time" Type="Decimal" />
</Cols>
I can do it with a simple replace logic and then load it but is there any build in functions for that in C#?

You can use System.IO.WebUtility or System.Web.HttpUtility
string s = "<Cols><Col idx="C1" Name="Speed" Type="Int" /><Col idx="C2" Name="Time" Type="Decimal" /></Cols>";
var xml = WebUtility.HtmlDecode(s); //OR HttpUtility.HtmlDecode(s);
var xDcoc = XDocument.Parse(xml);

Related

Error Xpath (System.ArgumentException: 'Noncompliant characters in the path.')

I have this error (translation from French Visual Studio error) when i try to Xpath a XML Data from a database :
System.ArgumentException: 'Noncompliant characters in the path.'
Error from Visual Studio (French)
This is my code :
public partial class WebForm1 : System.Web.UI.Page
{
SqlConnection connection = new SqlConnection(#"Data Source=SA2426\SQLEXPRESS;Initial Catalog=Proteor;Persist Security Info=True;User ID=sa;Password= root");
string query = "SELECT Content From Template WHERE Id = '0108f7ac-7853-4543-8ec4-a04cb755ed46' AND Deleted = '0'";
protected void Page_Load(object sender, EventArgs e)
{
try
{
SqlCommand cmd = new SqlCommand(query, connection);
connection.Open();
SqlDataReader sdr = cmd.ExecuteReader();
XmlDocument doc = new XmlDocument();
if(sdr.HasRows)
{
while(sdr.Read())
{
string content = sdr["Content"].ToString();
System.Diagnostics.Debug.WriteLine(System.Web.HttpUtility.HtmlDecode(content));
// Test Decode
string contenu = System.Web.HttpUtility.HtmlDecode(content);
doc.Load(System.Web.HttpUtility.HtmlDecode(content));
XmlNamespaceManager ns = new XmlNamespaceManager(doc.NameTable);
ns.AddNamespace("msbld", "http://schemas.microsoft.com/developer/msbuild/2003");
XmlNode FormId;
FormId = doc.SelectSingleNode("descendant::Properties/Property[attribute::Name='FormId']", ns);
System.Diagnostics.Debug.WriteLine(FormId.OuterXml);
}
}
}
finally
{
connection.Close();
}
}
}
I have to decode my XML, because special chars are included in this data, as "&lt","&gt"...
i don't know how is it possible... i copy/paste the "Test Decode" in a simple xml document so as to check the xml code, and it's alright :
<Root>
<StorageObject Name="OI-GENOUILLERE ODRA-v2" Id="0108f7ac-7853-4543-8ec4-a04cb755ed46" Type="Adviser.Proteor.Library.TemplateImpl">
<Properties>
<Property Name="TimeCreated" Value="27/07/2017 11:14:18" /><Property Name="Enabled" Value="True" /><Property Name="TimePublished" Value="01/01/0001 00:00:00" /><Property Name="TimeLastModified" Value="10/11/2017 09:09:29" /><Property Name="Description" Value="" /><Property Name="ObjectContent" Value=""<Template>
<Component Type="Adviser.Proteor.Library.TemplateImpl">
<ExtendedProperty Text="OI" Key="Classification" />
<ExtendedProperty Text="35176af2-b664-42d6-a7ba-5d06602b0500" Key="ClassificationId" />
<ExtendedProperty Text="GAO" Key="Activity" />
<ExtendedProperty Text="58d942ea-8cf7-4089-879c-f8633925473b" Key="ActivityId" />
<ExtendedProperty Text="OI 36" Key="AnatomicalLevel" />
<ExtendedProperty Text="76418da5-6830-4a49-aed0-b472c11c67c6" Key="AnatomicalLevelId" />
<ExtendedProperty Text="ORTHESE INF." Key="Type" />
<ExtendedProperty Text="13b33a27-57ce-4009-8812-00f8578982fd" Key="TypeId" />
<Version Version.Major="0" Version.Minor="1" />
<Properties>
<Property Name="TimeCreated" Value="27/07/2017 11:14:18" />
<Property Name="Enabled" Value="True" />
<Property Name="TimePublished" Value="01/01/0001 00:00:00" />
<Property Name="TimeLastModified" Value="10/11/2017 09:09:29" />
<Property Name="Description" Value="" />
</Properties>
<Component Type="Adviser.Proteor.Library.StepImpl">
<Properties>
<Property Name="FormId" Value="d442dce3-fc1f-49da-92c5-b25d89d76881" />
<Property Name="ValidationMode" Value="None" />
</Properties>
<Component Type="Adviser.Proteor.Library.Impl.Action.Task.OnPageLoadTrigger">
<Properties>
<Property Name="PageNumber" Value="1" />
</Properties>
<Component Type="Adviser.Proteor.Library.Impl.Action.Task.SetControlValueTask">
<Properties>
<Property Name="Text" Value="{agence}" />
<Property Name="ObjectId" Value="dc20a4e2-46d6-47fe-8c75-bf4d7ff012ba" />
</Properties>
</Component>
It's not the full code, but you can see that the code is correctly written.
Need help !!!
EDIT : There is something i've just seen at the moment. There is a xml code encapsulate in a main xml code :
the Value of the ObjectContent is not "finished" and starts with an other tag template
Per the docs for XmlDocument.Load, this overload:
Loads the XML document from the specified URL.
What you're passing it isn't an URL, it's a string that contains the XML content. This is why the error message states that you have invalid characters in your path - your XML isn't a path at all.
You want to use the XmlDocument.LoadXml method.

How dbml should be written when a stored procedure returns multiple result sets?

Is there any way to also modify dbml so that the method in designer.cs stays as IMultipleResults?
I have a stored procedure that returns 2 sets of data.
When I drag & drop the procedure to dbml, xml and designer.cs generated by dbml
<Function Name="dbo.MultiResultsTest" Method="MultiResultsTest">
<Parameter Name="iCustomerID" Type="System.Int32" DbType="Int" />
<Parameter Name="iProductID" Type="System.Int32" DbType="Int" />
<ElementType Name="MultiResultsTestResult">
<Column Name="CustomerID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
<Column Name="Name" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="Phone" Type="System.String" DbType="VarChar(14)" CanBeNull="true" />
<Column Name="Email" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="Address" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
</ElementType>
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.MultiResultsTest")]
public ISingleResult<MultiResultsTestResult> MultiResultsTest([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> iCustomerID, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> iProductID)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), iCustomerID, iProductID);
return ((ISingleResult<MultiResultsTestResult>)(result.ReturnValue));
}
And to get the multiple results I modified the designer.cs to like this:
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.MultiResultsTest")]
[ResultType(typeof(Customer))]
[ResultType(typeof(Product))]
public IMultipleResults MultiResultsTest([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> iCustomerID, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> iProductID)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), iCustomerID, iProductID);
return (IMultipleResults)(result.ReturnValue);
}
This works fine but because of the dbml, when I add more to it and save the method in designer.cs reverts back to the ISingleResult one.
After bit of searching and trying I found this way works!
<Function Name="dbo.MultiResultsTest" Method="MultiResultsTest">
<Parameter Name="iCustomerID" Type="System.Int32" DbType="Int" />
<Parameter Name="iProductID" Type="System.Int32" DbType="Int" />
<ElementType Name="CustomerResult">
<Column Name="CustomerID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
<Column Name="Name" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="Phone" Type="System.String" DbType="VarChar(14)" CanBeNull="true" />
<Column Name="Email" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="Address" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
</ElementType>
<ElementType Name="ProductResult">
<Column Name="ProductID" Type="System.Int32" DbType="Int NOT NULL" CanBeNull="false" />
<Column Name="ProductName" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
<Column Name="Price" Type="System.Decimal" DbType="Decimal(18,2)" CanBeNull="true" />
<Column Name="ModelNumber" Type="System.String" DbType="VarChar(MAX)" CanBeNull="true" />
</ElementType>
This generates the following method in designer.cs
[global::System.Data.Linq.Mapping.FunctionAttribute(Name="dbo.MultiResultsTest")]
[global::System.Data.Linq.Mapping.ResultTypeAttribute(typeof(CustomerResult))]
[global::System.Data.Linq.Mapping.ResultTypeAttribute(typeof(ProductResult))]
public IMultipleResults MultiResultsTest([global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> iCustomerID, [global::System.Data.Linq.Mapping.ParameterAttribute(DbType="Int")] System.Nullable<int> iProductID)
{
IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)(MethodInfo.GetCurrentMethod())), iCustomerID, iProductID);
return ((IMultipleResults)(result.ReturnValue));
}

Select attribute value from XDocument where another attribute equals specific string value

I have the following xml "example"
<methods>
<method name="listcust" >
<objects>
<object name="ExampleTest" type="" version="">
<properties>
<property name="FirstName" type="text">
<mappings>
<mapping type="property">
<property name="fn" />
</mapping>
</mappings>
</property>
<property name="LastName" type="text">
<mappings>
<mapping type="property">
<property name="ln" />
</mapping>
</mappings>
</property>
<property name="BirthDate" type="datetime">
<mappings>
<mapping type="property">
<property name="bd" />
</mapping>
</mappings>
</property>
</properties>
</object>
</objects>
</method>
</methods>
and Im trying to select the "name" atribute value of say
<property name="LastName" type="text">
when the "name" of the attribute within that element
is equal to "ln" <property name="ln" />
I tried the following
var query = from p in xdoc.Descendants("property")
where p.Descendants("property").Attributes("name").Contains(new XAttribute("name", "ln"))
select p.Attribute("name").Value;
var res = query.ToList<string>();
but I get zero results back.
If I break it down step by step
XDocument xdoc = XDocument.Parse(xml);
var props = xdoc.Descendants("property").Descendants("property");
var nameAtt = props.Attributes("name");
var contains = nameAtt.Contains(new XAttribute("name", "ln"));
Then I can see that nameAtt contains a list of the attributes including the <property name="ln" /> one but the contains bool is still false
If anyone can please point out the correct way of doing the select\where or perharps even a completely different more efficient way of retrieving the one attribute value where its child node attribute value equals the one passed in
Thanks
You just need to change the Where condition:
where p.Descendants("property").Any(x => (string)x.Attribute("name") == "In")
Any will check if there is any element that has name attribute equals to In

Getting nodes from a parent with a specific name atribute

I have the following XML document:
<database name="pressPlay">
<table name="users">
<column name="userID" type="INT" constraints="tableID_c" />
<column name="username" type="VARCHAR(50)" constraints="user_c" />
<column name="password" type="VARCHAR(50)" constraints="not_null_c" />
</table>
<table name="song">
<column name="songID" type="INT" constraints="tableID_c" />
<column name="albumID" type="INT" constraints="albumFK_c" />
<column name="artistID" type="INT" constraints="artistFK_c" />
<column name="songName" type="VARCHAR(50)" constraints="not_null_c" />
<column name="songDuration" type="VARCHAR(5)" constraints="not_null_c" />
<column name="link" type="VARCHAR(100)" />
</table>
<table name="album">
<column name="albumID" type="INT" constraints="tableID_c" />
<column name="albumName" type="VARCHAR(50)" constraints="not_null_c" />
<column name="albumGener" type="VARCHAR(50)" constraints="not_null_c" />
</table>
<table name="artist">
<column name="artistID" type="INT" constraints="tableID_c" />
<column name="artistName" type="VARCHAR(50)" constraints="not_null_c" />
</table>
<constraints>
<constraint name="tableID_c" type="unique" content="not_null" increment="auto"/>
<constraint name="user_c" type="unique" content="not_null"/>
<constraint name="not_null_c" content="not_null"/>
<constraint name="albumFK_c" type="forign_key" content="not_null" columns="album.albumID" />
<constraint name="artistFK_c" type="forign_key" content="not_null" columns="artist.artistID" />
</constraints>
</database>
now what i need is to get attributes from nodes that share a parent with a specific name attribute.
I tried to useXmlNodeList but that gives me all the nodes named column regardless of what the parents name is, i.e:
i need the name attributes from column nodes, with the parent name being users.
anyone know how to do this? i've been busting my head for a while now..
something Like that :
XmlDocument inventory = new XmlDocument();
inventory.Load("inventory.xml");
XmlNodeList elements = inventory.SelectNodes("/XMLProject/table[#name='users']/column");
foreach (XmlElement element in elements)
{
...
}
this will give you :
<column name="userID" type="INT" constraints="tableID_c" />
<column name="username" type="VARCHAR(50)" constraints="user_c" />
<column name="password" type="VARCHAR(50)" constraints="not_null_c" />
Now you can walk through each and take its attribute.
Something like this in Linq?
IEnumerable<string> names =
from x in XDocument.Load(#"project.xml").Descendants("column")
where x.Parent.Attribute("name").Value.Equals("users", StringComparison.Ordinal)
select x.Attribute("name").Value;
http://msdn.microsoft.com/en-us/library/bb387098.aspx
I would actually use LinqToXML in this case;
XDocument document = XDocument.Load("mydocument")
var table = (from n in document.Descendants("table")
where n.Attribute("name").Value == "users"
select n).Single( );
var columns = from c in table.Descendants("column")
select c.Attribute("name").Value;
That's a rough version, and I am certain there's a way to collapse them down into a single query. I find LinqToXml much easier to work with.

Cant Update row with Decimal DataType in Entity Frameworking using mySql

I have been working on this problem for too long. All of my select and insert commands work fine but when it comes to updating decimal columns i get errors.
I am using the following software
ASP.Net v4
MySQL Connector Net 6.3.3
MySql Server 5.0.51a
Product Class
public class Product()
{
public int ProductID {get;set;}
public string Name {get;set;}
public decimal Price {get;set;}
public string Description {get;set;}
}
The Code producing the error
var context = ObjectContextHelper.CurrentObjectContext;
var item = GetProductByID(ProductID);
if (!context.IsAttached(item))
context.Product.Attach(item);
item.Barcode = Barcode;
item.Price = Price;
item.ProductID = ProductID;
item.Name = Name;
item.Description = Description;
context.SaveChanges();
Database Schema
CREATE TABLE `product` (
`ProductID` int(10) unsigned NOT NULL auto_increment,
`Name` varchar(45) character set latin1 default NULL,
`Description` text character set latin1,
`Price` decimal(10,2) default NULL,
PRIMARY KEY (`ProductID`)
) ENGINE=MyISAM AUTO_INCREMENT=154 DEFAULT CHARSET=utf8 PACK_KEYS=1$$
The inner exception error i receive is
InnerException = {"The specified value is not an instance of type 'Edm.Int64'\r\nParameter name: value"}
The error doesn't fire if you stop the update to the Price Column.
This is the Entity Mappings
<?xml version="1.0" encoding="utf-8"?>
<edmx:Edmx Version="2.0" xmlns:edmx="http://schemas.microsoft.com/ado/2008/10/edmx">
<!-- EF Runtime content -->
<edmx:Runtime>
<!-- SSDL content -->
<edmx:StorageModels>
<Schema Namespace="Wombat.Store" Alias="Self" Provider="MySql.Data.MySqlClient" ProviderManifestToken="5.0" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" xmlns="http://schemas.microsoft.com/ado/2009/02/edm/ssdl">
<EntityContainer Name="WombatStoreContainer">
<EntitySet Name="product" EntityType="Wombat.Store.Product" store:Type="Tables" Schema="charlees" />
</EntityContainer>
<EntityType Name="product">
<Key>
<PropertyRef Name="ProductID" />
</Key>
<Property Name="Price" Type="decimal" Scale="2" />
<Property Name="ProductID" Type="uint" Nullable="false" StoreGeneratedPattern="Identity" />
<Property Name="Name" Type="varchar" MaxLength="45" />
<Property Name="Description" Type="text" />
</EntityType>
<Function Name="isNullDecimal" ReturnType="decimal" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="charlees" />
</Schema>
</edmx:StorageModels>
<!-- CSDL content -->
<edmx:ConceptualModels>
<Schema xmlns="http://schemas.microsoft.com/ado/2008/09/edm" xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration" xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" Namespace="Wombat.Commerce.Data" Alias="Self" xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation">
<EntityContainer Name="WombatEntities" annotation:LazyLoadingEnabled="true">
<EntitySet Name="Products" EntityType="Wombat.Commerce.Data.Product" />
</EntityContainer>
<EntityType Name="Product">
<Key>
<PropertyRef Name="ProductID" />
</Key>
<Property Type="Decimal" Name="Price" Nullable="true" />
<Property Type="Int32" Name="ProductID" Nullable="false" annotation:StoreGeneratedPattern="Identity" />
<Property Type="String" Name="Name" />
<Property Type="String" Name="ShortDescription" />
<Property Type="String" Name="Sku" />
</EntityType>
</Schema>
</edmx:ConceptualModels>
<!-- C-S mapping content -->
<edmx:Mappings>
<Mapping xmlns="http://schemas.microsoft.com/ado/2008/09/mapping/cs" Space="C-S">
<Alias Key="Model" Value="Wombat" />
<Alias Key="Target" Value="Wombat.Store" />
<EntityContainerMapping CdmEntityContainer="WombatEntities" StorageEntityContainer="WombatStoreContainer">
<EntitySetMapping Name="Products">
<EntityTypeMapping TypeName="Wombat.Commerce.Data.Product">
<MappingFragment StoreEntitySet="product">
<ScalarProperty Name="Description" ColumnName="Description" />
<ScalarProperty Name="Name" ColumnName="Name" />
<ScalarProperty Name="ProductID" ColumnName="ProductID" />
<ScalarProperty Name="Price" ColumnName="Price" />
</MappingFragment>
</EntityTypeMapping>
</EntitySetMapping>
</EntityContainerMapping>
</Mapping>
</edmx:Mappings>
</edmx:Runtime>
</edmx:Edmx>
This appears to be a similar problem to yours.
http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/1e40d986-4e5c-4da1-a526-b8cf472fb4d5
You'll have to make a wrapper property of type Int64.

Categories

Resources