使用XElement中的位置获取属性名称

时间:2015-08-28 09:22:55

标签: c# xml linq collections

我在数据定义文件中有以下XML:

<PQTemplate documentID="CSTrlsEN" documentType="TransList" templateID="001" 
            templateType="Customer Copy" 
            templateName="C:\CPS\_templates\Mini-Statements\CSTrlsEN.doc">  
    <field pos="5" name="YPTME" descr="Time"  />
    <field pos="6" name="YPDTE" descr="Action Date"  />
    <field pos="7" name="YPBRNO" descr="Branch Number"  />
    <field pos="8" name="YPBNA" descr="Branch Name"  />
    <field pos="9" name="YPTID" descr="Teller ID"  />
    <field pos="10" name="YPISN" descr="Teller Sequence"  />
    <field pos="11" name="YPREF" descr="Customer Reference"  />
    <field pos="12" name="YPCUS" descr="Customer Name"  />
    <field pos="13" name="YPEAN" descr="Account Number"  />
    <field pos="14" name="YPATY" descr="Account Type"  />
    <field pos="15" name="YPCUR" descr="Currency"  />
    <field pos="16" name="YPBAL" descr="Available Balance"  />
</PQTemplate>

我想通过在字段子元素中添加为 name 属性命名的列来构建数据表,但是我在使用LINQ检索信息时遇到问题:

以下是我要编写的代码,我想使用 pos 属性> 5的属性名称添加列名,因此第一列将是 YPTME ,第二列将是 YPDTE ,依此类推,直到添加的第12列和最后一列 YPBAL ......

var mapInfo = from nm in XElement.Elements("PQTemplate").Elements("field")
                where (string)nm.Attribute("documentID") == sRequests[0] 
                select nm;

if (mapInfo != null)
{
    for (int iCol = 5; iCol < mapInfo.Count(); iCol++) 
    { 
        // there should be twelve
        string colName = mapInfo.Attributes(iCol);
        dt[0].Columns.Add(new DataColumn(colName, typeof(System.String)));
    }
}

我似乎无法正确地做到这一点,我怎么能这样做?我在哪里出错string colName = mapInfo.Attributes(iCol);

修改

我也试过这个,但是再一次,似乎无法在for..next循环中应用索引:

var mapInfo = from nm in XElement.Elements("PQTemplate").Elements("field")
            where (string)nm.Attribute("documentID") == sRequests[0] && Convert.ToInt32(nm.Attribute("pos").ToString())>=5 
            orderby Convert.ToInt32(nm.Attribute("pos").ToString())
            select nm;

if (mapInfo != null)
{
    for (int iDx=5; iDx<mapInfo.Count(); iDx++)
    {
    string colName=mapInfo[iDx];
    dt[0].Columns.Add(new DataColumn(colName, typeof(System.String)));
            }
    }

由于

2 个答案:

答案 0 :(得分:1)

试试这个

        XElement rootElement = XElement.Parse(stringXml);
        DataTable dt = new DataTable();
        if (rootElement.Attribute("documentID").Value == "CSTrlsEN")
        {
             var colNames = from field in rootElement.Elements("field")
                          where Convert.ToInt32(field.Attribute("pos").Value) >= 5
                          select field.Attribute("name").Value;

             foreach (var name in colNames)
             {
                 dt.Columns.Add(name, typeof(string));
             }
        }

答案 1 :(得分:1)

这应该适合你: -

 IEnumerable<string> columnNames = from nm in xdoc.Descendants("field")
                          where (string)nm.Parent.Attribute("documentID") == "CSTrlsEN"
                                              && (int)nm.Attribute("pos") >= 5
                          select (string)nm.Attribute("name");

或者如果你想对documentID进行验证,你可以按照@codeninja的建议使用if块。

这将为您提供具有指定条件的所有列名称,然后您可以简单地遍历它: -

 foreach (var colName in columnNames)
 {
     dt[0].Columns.Add(new DataColumn(colName, typeof(System.String)));
 }