Title = (String)x.Elements()
.Where(e => e.Name.LocalName == "Title")
.Single();
OR
delcare namepace
XNamespace ns="http://www.website.co.za/namespace";
and refer it
Title = (String)x.Element(ns+"Title")
Вопрос
I am using the following query to convert XML to a struct. If an element does not exist how would I accommodate for it in the following query(ClntCde will always exist but there is a chance Title will not exist)
ClientTbl ClientData = clientNode.Select(x => new ClientTbl
{
ClientCode = x.Elements().Where(e => e.Name.LocalName == "ClntCde").FirstOrDefault().Value,
//Title = x.Elements().Where(e => e.Name.LocalName == "Title").ToString(),
//Title = x.Elements().Where(e => e.Name.LocalName == "Title").FirstOrDefault().Value,
//Title = x.Elements("Title").FirstOrDefault().Value,
}
).First();
The XML:
<Client xmlns="http://www.website.co.za/namespace">
<ClntCde>0000013</ClntCde>
<Surname>Account Holder Surname</Surname>
<Address>
<Addr1>.</Addr1>
<Addr2>.</Addr2>
<Addr3>.</Addr3>
<Addr4>.</Addr4>
<PostCde>2000</PostCde>
</Address>
<ClntAccTyp>A</ClntAccTyp>
<ElecInd>NO</ElecInd>
<Lang>ENG</Lang>
</Client>
Решение 2
Title = (String)x.Elements()
.Where(e => e.Name.LocalName == "Title")
.Single();
OR
delcare namepace
XNamespace ns="http://www.website.co.za/namespace";
and refer it
Title = (String)x.Element(ns+"Title")
Другие советы
You can use DefaultIfEmpty("")
:
ClientCode = x.Elements()
.Where(e => e.Name.LocalName == "ClntCde")
.Select(e => e.Value)
.DefaultIfEmpty("")
.First(),
Title = x.Elements()
.Where(e => e.Name.LocalName == "Title")
.Select(e => e.Value)
.DefaultIfEmpty("")
.First(),
// ...
Note that the ...OrDefault
is redundant if you provide a default value yourself. It is safe to call First
or Single
(can still throw on multiple elements) since it can never be empty.
Try:
Title = x.Elements()
.Where(e => e.Name.LocalName == "Title")
.Select(e => e.Value)
.FirstOrDefault() ?? string.Empty;
var ns = clientNode.GetDefaultNamespace();
ClientTbl ClientData = clientNode.Select(x => new ClientTbl
{
ClientCode = (string)x.Element(ns + "ClntCde") ?? string.Empty,
Title = (string)x.Element(ns + "Title") ?? string.Empty,
}
).First();
Update 1: added default namespace
Update 2: added blank string if element does not exists
Using this XML Library you can reference each element directly and give a default value if it doesn't exist like so:
ClientTbl ClientData = clientNode.Select(x => new ClientTbl
{
ClientCode = x.Get("ClntCde", "defaultCode"),
Title = x.Get("Title", "defaultTitle"),
Addr1 = x.Get("Address/Addr1", "addr1 default"),
// and/or
Address = x.GetElement("Address") // Creates the Address node if doesn't exist
.Select(a => new
{
Addr1 = a.Get("Addr1", "addr1 default"),
// etc
})
});
The default is type specific. If your code is always numeric, you can use a numeric default and it will be that type. Get
also handles the namespace.
Get has the syntax of (in this case):
T Get<T>(string name, T defaultValue);