Select attribute value from XDocument where another attribute equals specific string value - c#

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

Related

Get value between xml tags having a "title" as value in name attribute?

I'm currently importing webparts using a file upload control containing collection of webPartDescription (XML)
<wrapper>
<webParts>
<webPart xmlns="http://schemas.microsoft.com/WebPart/v3">
<metaData>
<type src="~/Web/Controls/Test/TestHeaderList.ascx" />
<importErrorMessage>Cannot import this Web Part.</importErrorMessage>
</metaData>
<data>
<properties>
<property name="UserCancelled" type="bool">False</property>
<property name="AllowedRoles" type="string" null="true" />
<property name="SourceFileName" type="bool">False</property>
<property name="ViewFilterExpression" type="string" />
<property name="UserCreated" type="bool">False</property>
<property name="HideExportButtons" type="bool">False</property>
<property name="RecordCount" type="bool">False</property>
<property name="TransferStatus" type="bool">False</property>
<property name="OrdersHeaderID" type="bool">False</property>
<property name="TransmitRecordCount" type="bool">False</property>
<property name="DataSource" type="Lobas.Demo.Web.Controls.Test+Views, Test.Demo.Web, Version=2.2.0.0, Culture=neutral, PublicKeyToken=null">None</property>
<property name="DeltaCount" type="bool">False</property>
<property name="OrdersHeaderBatchNo" type="bool">False</property>
<property name="DateCancelled" type="bool">False</property>
<property name="ResponseDescription" type="bool">False</property>
<property name="RunDate" type="bool">False</property>
<property name="DateCreated" type="bool">False</property>
<property name="ResponseCode" type="bool">False</property>
</properties>
<genericWebPartProperties>
<property name="Width" type="unit" />
<property name="Description" type="string" />
<property name="AllowEdit" type="bool">True</property>
<property name="ChromeType" type="chrometype">Default</property>
<property name="TitleIconImageUrl" type="string" />
<property name="Hidden" type="bool">False</property>
<property name="TitleUrl" type="string" />
<property name="AllowClose" type="bool">True</property>
<property name="AllowMinimize" type="bool">True</property>
<property name="AllowConnect" type="bool">True</property>
<property name="Height" type="unit" />
<property name="HelpMode" type="helpmode">Navigate</property>
<property name="Title" type="string">Orders Header List</property>
<property name="CatalogIconImageUrl" type="string" />
<property name="Direction" type="direction">NotSet</property>
<property name="AllowZoneChange" type="bool">True</property>
<property name="ChromeState" type="chromestate">Normal</property>
<property name="HelpUrl" type="string" />
<property name="AllowHide" type="bool">True</property>
<property name="ExportMode" type="exportmode">NonSensitiveData</property>
</genericWebPartProperties>
</data>
</webPart>
</webParts>
</wrapper>
i want to filter and fetch the value of property element inside "genericWebPartProperties" with attribute name ="Title"
eg : Orders Header List (in above xml)
i'm new to linq and xml. i tried several solutions but received null
My code behind looks like :
//Uploded xml containing multible webparts wraped under <wrapepr> root tag.
XDocument UploadedXmlWebparts = XDocument.Load(e.UploadedFile.FileContent);
// fetching individual webpart xml and storing in a Xelement Collection
var WebpartCollection = UploadedXmlWebparts.Root.Elements();
List<ClsImportWp> WebPartDescriptionList = new List<ClsImportWp>();
foreach (XElement webPart in WebpartCollection)
{
var TitleName = // Get the title tag value here
}
Use xml linq with a dictionary :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
namespace ConsoleApplication166
{
class Program
{
const string FILENAME = #"c:\temp\test.xml";
static void Main(string[] args)
{
XDocument doc = XDocument.Load(FILENAME);
XElement genericWebPartProperties = doc.Descendants().Where(x => x.Name.LocalName == "genericWebPartProperties").FirstOrDefault();
XNamespace ns = genericWebPartProperties.GetDefaultNamespace();
Dictionary<string,string> dict = genericWebPartProperties.Elements(ns + "property")
.GroupBy(x => (string)x.Attribute("name"), y => (string)y)
.ToDictionary(x => x.Key, y => y.FirstOrDefault());
}
}
}

OData V4 .NET core nested properties cannot be translated from Linq

I am trying to get the OData Query "orderby" on a nested property to work on .Net Core 3.1
According to my reading the correct query should be formatted like this:
https://{server}:{port}/v1/Entities?$expand=ownBy&$orderby=ownBy/userName
and I get the following error message:
System.InvalidOperationException: The LINQ expression 'DbSet<Entity>
.LeftJoin(
outer: DbSet<User>,
inner: p => EF.Property<Nullable<Guid>>(p, "OwnById"),
outerKeySelector: u => EF.Property<Nullable<Guid>>(u, "UserId"),
innerKeySelector: (o, i) => new TransparentIdentifier<Portfolio, User>(
Outer = o,
Inner = i
))
.OrderBy(p => EF.Property<Nullable<Guid>>(p.Inner, "UserId") == null ? null : new UserModel{
UserEmail = p.Inner.UserEmail,
UserFirstName = p.Inner.UserFirstName,
UserId = p.Inner.UserId,
UserLastName = p.Inner.UserLastName,
Username = p.Inner.Username
}
.Username)' could not be translated.
It seems to be a fairly simple example and I don't understand why this is so complex to translate.
Here is my controller using automapper:
[ODataRoute]
[Produces("application/json")]
[ProducesResponseType(typeof(ODataValue<IEnumerable<EntityModel>>), Status200OK)]
[ProducesResponseType(Status404NotFound)]
[EnableQuery(AllowedQueryOptions = All, MaxTop = 100)]
public IQueryable<EntityModel> Get()
{
var results = _Query.Get();
return results.ProjectTo<EntityModel>(_Mapper.ConfigurationProvider);
}
Automapper config:
CreateMap<Entity, EntityModel>();
Metadata:
<EntityType Name="EntityModel">
<Key>
<PropertyRef Name="entityId" />
</Key>
...
<Property Name="ownById" Type="Edm.Guid" />
...
<NavigationProperty Name="ownBy" Type="AMI.UserModel" />
</EntityType>
<EntityType Name="UserModel">
<Key>
<PropertyRef Name="userId" />
</Key>
<Property Name="userId" Type="Edm.Guid" Nullable="false" />
<Property Name="username" Type="Edm.String" />
<Property Name="userFirstName" Type="Edm.String" />
<Property Name="userLastName" Type="Edm.String" />
<Property Name="userEmail" Type="Edm.String" />
</EntityType>
Any help would be very much appreciated.

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.

Pick out a group of items using linq to xml

My head is fuzzled with this. I have an xml doc which has the layout for a grid stored in it. If you notice the columns are stored as "Items" in the XML. I am trying to retrieve each "Item" out of the XML using LINQ but no matter what I do I keep taking on straggler properties that I don't need. Any help would be much appreciated.
<?xml version="1.0" encoding="utf-16" ?>
<DatagridView>
<ViewType>DevExpress.XtraGrid.Views.Grid.GridView</ViewType>
<ViewLayout>
<property name="Columns" iskey="true" value="9">
<property name="Item1" isnull="true" iskey="true">
<property name="VisibleIndex">0</property>
<property name="Visible">true</property>
<property name="Width">1249</property>
<property name="SummaryItem" isnull="true" iskey="true">
<property name="SummaryType">Count</property>
<property name="DisplayFormat">{0}</property>
<property name="FieldName">Comments</property>
<property name="Tag" isnull="true" />
</property>
<property name="Name">colComments</property>
<property name="ColumnEditName" />
<property name="FieldName">Comments</property>
</property>
<property name="Item2" isnull="true" iskey="true">
<property name="VisibleIndex">1</property>
<property name="Visible">true</property>
<property name="Width">197</property>
<property name="Name">colEvent</property>
<property name="ColumnEditName" />
<property name="FieldName">Event</property>
</property>
......
EDIT:
To be clear, the XML can contain any number of columns represented like so:
<property name="Item2" isnull="true" iskey="true">
<property name="VisibleIndex">1</property>
<property name="Visible">true</property>
<property name="Width">197</property>
<property name="Name">colEvent</property>
<property name="ColumnEditName" />
<property name="FieldName">Event</property>
</property>
I would like to grab those chunks of data in that same order via XML.
Well, you could just get the property elements directly beneath "Columns":
// TODO: Work out what to do if there are zero or multiple such elements
var columns = xdoc.Descendants("property")
.Where(x => (string) x.Attribute("name") == "Columns")
.Single();
var items = columns.Elements("property");
foreach (var item in items)
{
Console.WriteLine("Item {0}", (string) item.Attribute("name"));
foreach (var property in items.Elements("property"))
{
Console.WriteLine(" {0} = {1}", (string) item.Attribute("name"),
(string) item);
}
}

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