Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/331.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从列表中使用Linq构建XML<;定制类>;_C#_Xml_Linq_Linq To Xml - Fatal编程技术网

C# 从列表中使用Linq构建XML<;定制类>;

C# 从列表中使用Linq构建XML<;定制类>;,c#,xml,linq,linq-to-xml,C#,Xml,Linq,Linq To Xml,我只是试着理解Linq,我试着做一些看起来很简单的事情,但是我不能让它以我想要的方式输出。这几天来我一直在尝试各种不同的方法,但我就是做不好 所以我有一个类EarObs,它有成员:eventID,icaoId,frm,sta,db 我正试图从列表中构建一个XML文档。我希望XML文档如下所示: 87 99 79 99 ................ 如果有多个帧或多个代码等,这将一直保持相同的顺序 所以这就是我最近一直在尝试的,但它仍然没有以我想要的方式输出它们,Obs会重复出现,我不知道

我只是试着理解Linq,我试着做一些看起来很简单的事情,但是我不能让它以我想要的方式输出。这几天来我一直在尝试各种不同的方法,但我就是做不好

所以我有一个类EarObs,它有成员:eventID,icaoId,frm,sta,db

我正试图从列表中构建一个XML文档。我希望XML文档如下所示:


87
99
79
99
................
如果有多个帧或多个代码等,这将一直保持相同的顺序

所以这就是我最近一直在尝试的,但它仍然没有以我想要的方式输出它们,Obs会重复出现,我不知道哪里出了问题

string eventGUID=“eventGUID”;
List frameObsList=新列表();
对于(int-frm=2;frm>0;frm--)
{
对于(int sta=5;sta>0;sta--)
{
添加(新的EarObs(“KAPF”,事件GUID,frm,sta,85+sta,99+sta));
cnt++;
}
}
字符串eventID=obsList.First().EventGUID;
列出不同的标签=
障碍名单
.GroupBy(p=>p.IcaoId)
.Select(g=>g.First())
.ToList();
XElement XElement=新XElement(“EarObs”,新XAttribute(“eventID”,eventID),
从ea到distinctApts
orderbyea.IcaoId
选择新XElement(“icao”,新XAttribute(“代码”,ea.IcaoId),
来自OBS列表中的eb
其中ea.IcaoId==eb.IcaoId
订购者eb.Frm
选择新XElement(“frm”),新XAttribute(“frm”,eb.frm),
来自obsList中的ec
其中eb.Frm==ec.Frm
欧共体订购
选择新元素(“sta”,新XAttribute(“sta”,ec.sta),
新XElement(“db”,ec.db),
新XElement(“hz”,ec.hz()()));
使用这段代码,我得到一个xml文档,它为每个站点重复帧一次。这是不对的。我觉得这很容易按顺序完成,但我正在努力学习,这似乎很简单,我应该能够在Linq中完成。我需要列表中的每个元素只在XML文档中表示一次。我该怎么办


我还想对它进行扩展,以便它也可以处理多个eventId,但这并不像正确使用XML结构那么重要。任何帮助都将不胜感激,我还没有找到太多创建XML的示例,包括使用linq过滤元素,大多数示例在创建XML之前似乎都已准备好结构化列表。

因为您有一个自定义类,EarObs为什么不为对象定义Xml属性,并使用XmlSerlizer类序列化对象?这样,您可以继续在对象上使用Linq,也可以输出对象

e、 下面是一支球队,队员们在上面

[XmlRoot("root")]
public class Team
{
    private List<Player> players = new List<Player>();

    [XmlElement("player")]
    public List<Player> Players { get { return this.players; } set { this.players = value; } }

    // serializer requires a parameterless constructor class
    public Team() { }
}

public class Player
{
    private List<int> verticalLeaps = new List<int>();

    [XmlElement]
    public string FirstName { get; set; }
    [XmlElement]
    public string LastName { get; set; }
    [XmlElement]
    public List<int> vertLeap { get { return this.verticalLeaps; } set { this.verticalLeaps = value; } }

    // serializer requires a parameterless constructor class
    public Player() { }
}
输出如下所示:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <player>
    <FirstName>dwight</FirstName>
    <LastName>howard</LastName>
    <vertLeap>1</vertLeap>
    <vertLeap>2</vertLeap>
    <vertLeap>3</vertLeap>
  </player>
  <player>
    <FirstName>dwight</FirstName>
    <LastName>howard</LastName>
    <vertLeap>1</vertLeap>
  </player>
</root>

德怀特
霍华德
1.
2.
3.
德怀特
霍华德
1.

最简单的方法是创建一组类来处理序列化,就像这样

public class sta
{
    public int db { get; set; }
    public int hz { get; set; }

    [XmlAttribute()]
    public string station { get; set; }
}

public class frm
{
    [XmlAttribute("frm")]
    public string frmID { get; set; }

    [XmlElement("sta")]
    public List<sta> stas { get; set; }
}

public class icao
{
    [XmlAttribute]
    public string icaoID { get; set; }

    [XmlElement("frm")]
    public List<frm> frms { get; set; }
}

public class EarObs
{
    [XmlAttribute]
    public string EventId { get; set; }

    [XmlElement("icao")]
    public List<icao> icaos { get; set; }
}
公共类sta
{
公共int db{get;set;}
公共int hz{get;set;}
[XmlAttribute()]
公共字符串站{get;set;}
}
公共类frm
{
[XmlAttribute(“frm”)]
公共字符串frmID{get;set;}
[XmlElement(“sta”)]
公共列表stas{get;set;}
}
国际民航组织公务舱
{
[XmlAttribute]
公共字符串icaoID{get;set;}
[XmlElement(“frm”)]
公共列表frms{get;set;}
}
公共类EarObs
{
[XmlAttribute]
公共字符串EventId{get;set;}
[XmlElement(“icao”)]
公共列表icaos{get;set;}
}
您可以使用xml序列化程序进行序列化/反序列化。以下内容序列化为与现有结构相同的结构

XmlSerializer serializer = new XmlSerializer(typeof(EarObs));
EarObs obs = new EarObs() { EventId = "123456789" };
obs.icaos = new List<icao>();
obs.icaos.Add(new icao() { icaoID = "0001" });
obs.icaos[0].frms = new List<frm>();
obs.icaos[0].frms.Add(new frm() { frmID = "01" });
obs.icaos[0].frms[0].stas = new List<sta>();
obs.icaos[0].frms[0].stas.Add(new sta() { station = "00", db = 87, hz = 99 });
obs.icaos[0].frms[0].stas.Add(new sta() { station = "01", db = 79, hz = 99 });
obs.icaos[0].frms.Add(new frm() { frmID = "02" });

using (StringWriter s = new StringWriter())
{
    serializer.Serialize(s, obs);
    string test = s.ToString();
}
XmlSerializer serializer=新的XmlSerializer(typeof(EarObs));
EarObs obs=new EarObs(){EventId=“123456789”};
obs.icaos=新列表();
添加(新的icao(){icaoID=“0001”});
obs.icaos[0].frms=new List();
obs.icaos[0].frms.Add(new frm(){frmID=“01”});
obs.icaos[0].frms[0].stats=new List();
obs.icaos[0].frms[0].stas.Add(new sta(){station=“00”,db=87,hz=99});
obs.icaos[0].frms[0].stas.Add(new sta(){station=“01”,db=79,hz=99});
obs.icaos[0].frms.Add(new frm(){frmID=“02”});
使用(StringWriter s=new StringWriter())
{
序列化器。序列化(s,obs);
字符串测试=s.ToString();
}
产出

<?xml version="1.0" encoding="utf-16"?>
<EarObs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" EventId="123456789">
  <icao icaoID="0001">
    <frm frm="01">
      <sta station="00">
        <db>87</db>
        <hz>99</hz>
      </sta>
      <sta station="01">
        <db>79</db>
        <hz>99</hz>
      </sta>
    </frm>
    <frm frm="02" />
  </icao>
</EarObs>

87
99
79
99

现在,虽然这看起来有很多麻烦,但是可以使用xsd.exe工具(我相信是框架附带的)来自动创建一组与任何给定xml文件匹配的类,尽管它确实使用了一个中间xsd文件(尽管没有痛苦)。你可以在这里找到答案

它可能不“正确”,但它完全按照指示进行-在站点上循环时,为每个迭代添加一个对象。您可能打算将电台添加到本地集合,然后添加一个包含电台集合的帧。那么您是说我应该在select sta元素行下添加另一个from语句吗?您能详细说明一下将电台添加到本地集合的含义吗?在此之前,当您构建FrameOBList时,为每个电台添加一个。基本上,即使您不使用数据库,你有一个规范化问题。你是说我应该制作一个类似于distinctApts的列表,然后在from语句中使用它?对不起,我完全搞糊涂了,我没有改变XML格式的选择。我可以用其他的方法来做,我知道,我只是想控制一下林克。我会比威利做得更好
<?xml version="1.0" encoding="utf-16"?>
<EarObs xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" EventId="123456789">
  <icao icaoID="0001">
    <frm frm="01">
      <sta station="00">
        <db>87</db>
        <hz>99</hz>
      </sta>
      <sta station="01">
        <db>79</db>
        <hz>99</hz>
      </sta>
    </frm>
    <frm frm="02" />
  </icao>
</EarObs>