[英]How to handling null, blank or no Element found issues in Linq-To-Xml?
[英]Handling null values and missing columns in Linq-to-Xml
我有一個用戶提供的DataTable,其中包含以下信息:
| Name | Alias |
|---------------------------
| Batman | Dark Knight |
| Superman | Man of Steel |
| Spiderman | null |
我需要將此表轉換為Xml以發送到存儲過程並獲取類似於以下內容的Xml:
<Superheroes>
<Superhero Name="Batman" Alias="Dark Knight"/>
<Superhero Name="Superman" Alias="Man of Steel"/>
<Superhero Name="Spiderman"/>
</Superheroes>
我想使用Linq-to-Xml(出於學習目的)解決此問題。 這是我到目前為止的內容:
XDocument doc;
doc = new XDocument(
new XElement("Superheroes",
from row in table.AsEnumerable()
select new XElement("Superhero",
new XAttribute("Name", row.Field<string>("Name")),
new XAttribute("Alias", row.Field<string>("Alias"))
)));
問題是蜘蛛俠行。 上面的查詢由於為null而無法正常工作。
問題
如何處理Linq-to-Xml中的空Spiderman行?
如果用戶忘記添加Alias行,則需要能夠處理該請求。 在這種情況下,別名應該是(a)完全不在Xml中,或者(b)具有空值
您可以為此編寫一個輔助函數,該函數將返回XAttribute
或null
。 Linq to XML只會忽略null
。
private XAttribute GetAlias(DataRow row)
{
if(row.Field<string>("Alias") != null)
{
return new XAttribute("Alias", row.Field<string>("Alias"));
}
return null;
}
並像這樣使用它。
doc = new XDocument(
new XElement("Superheroes",
from row in table.AsEnumerable()
select new XElement("Superhero",
new XAttribute("Name", row.Field<string>("Name")),
GetAlias(row)
)));
如果缺少Alias列,這也應該起作用,因為如果缺少列,則Field<T>(string)
擴展方法應返回null
。
或者,如果你只是想有一個空字符串的屬性時,該列是丟失或值為null
,你可以做到以下幾點。
doc = new XDocument(
new XElement("Superheroes",
from row in table.AsEnumerable()
select new XElement("Superhero",
new XAttribute("Name", row.Field<string>("Name")),
new XAttribute("Alias", row.Field<string>("Alias") ?? string.Empty)
)));
另一種方法是像在第一個答案中那樣使用三元運算符: 具有三元運算符的示例
如果屬性名稱應與列標題相同,則是另一種解決方案。 您只能添加沒有空值的那些屬性:
doc = new XDocument(
new XElement("Superheroes",
from row in table.AsEnumerable()
select new XElement("Superhero",
from column in table.Columns.Cast<DataColumn>()
let value = row.Field<string>(column)
where value != null // just filter out nulls
select new XAttribute(column.Caption, value)
)));
BTW蜘蛛俠不如蝙蝠俠或超人好
實際上,您可以創建以下擴展名,該擴展名將基於表名和列名從任何DataTable構建xml(它需要System.Data.Entity.Design程序集中的PluralizationService):
public static class Extensions
{
public static XDocument ToXml(this DataTable table)
{
if (String.IsNullOrEmpty(table.TableName))
throw new ArgumentException("Table name is required");
var pluralizationService = PluralizationService
.CreateService(new CultureInfo("en-US"));
string elementName = pluralizationService.Singularize(table.TableName);
return new XDocument(
new XElement(table.TableName,
from row in table.AsEnumerable()
select new XElement(elementName,
from column in table.Columns.Cast<DataColumn>()
let value = row.Field<string>(column)
where value != null
select new XAttribute(column.Caption, value)
)
)
);
}
}
用法很簡單:
DataTable table = new DataTable("Superheroes"); // name is required
table.Columns.Add("Name");
table.Columns.Add("Alias");
table.Rows.Add("Batman", "Dark Knight");
table.Rows.Add("Superman", "Man Of Steel");
table.Rows.Add("Spiderman", null);
var doc = table.ToXml();
結果很不錯
<Superheroes>
<Superhero Name="Batman" Alias="Dark Knight" />
<Superhero Name="Superman" Alias="Man Of Steel" />
<Superhero Name="Spiderman" />
</Superheroes>
您可以使用內聯if
語句(使用?:
operator )擴展查詢,並檢查當前行中是否設置了Alias
:
doc = new XDocument(
new XElement("Superheroes",
from row in table.AsEnumerable()
select new XElement("Superhero",
new XAttribute("Name", row.Field<string>("Name")),
(row.Field<string>("Alias") != null ? new XAttribute("Alias", row.Field<string>("Alias")) : null))
));
返回null
根本不會更改生成的XML,因此doc
包含您希望它包含的內容:
<Superheroes>
<Superhero Name="Batman" Alias="Dark Knight" />
<Superhero Name="Superman" Alias="Man of Steel" />
<Superhero Name="Spiderman" />
</Superheroes>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.