【问题标题】:Flatten a Parent/Child hierarchy [closed]展平父/子层次结构[关闭]
【发布时间】:2014-04-09 18:48:23
【问题描述】:

我在这里试图理解一个概念:

从一个像这样的对象结构

class Parent
{
    public string ParentID { get; set; }
    public List<Child> Children { get; set; } 
}

class Child
{
   public string ChildID { get; set; }
}

假设一个完全填充的父对象,我想使用 Linq to Xml 来获得以下 Xml 输出:

<Mappings>
   <Mapping ID='ParentID1' ChildID='ChildID1'>
   <Mapping ID='ParentID1' ChildID='ChildID2'>
</Mappings>

如何展开嵌套的原始对象以获得此映射列表?

编辑

以父母为例,例如:

ParentID = 'Parent1', Children = new [] { "Child1", "Child2", "Child3" }

我期待 3 个映射:

<Mapping ID='Parent1' ChildID='Child1' />
<Mapping ID='Parent1' ChildID='Child2' />
<Mapping ID='Parent1' ChildID='Child3' />

【问题讨论】:

  • Assuming a fully populated parent object,发个帖子怎么样?
  • 我不明白您希望看到什么。这是一个概念问题。将填充 ParentID 和 ChildID 值的实际字符串文字对解决方案无关紧要。因此,没有什么可发布的。
  • 到目前为止,您在尝试生成此类文件时做了哪些尝试?具体来说,您在该实施中遇到了什么问题?
  • 我不明白如何在 linq-to-xml 语法中有效地构建它,因为在创建第一个“映射”XElement 时,我需要每个条目的 ChildID 值,但我不知道如何用语法来表达。
  • 看来编辑此问题标题的天才设法删除了大部分上下文,即我想要一个 linq-to-xml 语法的解决方案。一个解决方案就足够了,因为提供了样本输入和输出。这太宽泛了,简直是疯了。

标签: c# xml linq linq-to-xml


【解决方案1】:

编辑

以下代码将扁平化层次结构:

var list = new List<Parent>
{
    new Parent
    {
        ParentID = "parentID1",
        Children = new List<Child> {new Child {ChildID = "childID1"}, new Child {ChildID = "childID2"}}
    },
    new Parent
    {
        ParentID = "parentID2",
        Children = new List<Child> {new Child {ChildID = "childID3"}, new Child {ChildID = "childID4"}}
    }
};

IEnumerable<XElement> list1 = (from parent in list
    from child in parent.Children
    select
        new XElement("Mapping", new XAttribute("ID", parent.ParentID),
            new XAttribute("ChildID", child.ChildID)));

string @join = string.Join(Environment.NewLine, list1);

输出:

<Mapping ID="parentID1" ChildID="childID1" />
<Mapping ID="parentID1" ChildID="childID2" />
<Mapping ID="parentID2" ChildID="childID3" />
<Mapping ID="parentID2" ChildID="childID4" />

这是一个关于如何实现它的示例:

注意:这不起作用,它会生成一个异常,说“重复属性”

List<Parent> list = new List<Parent>
{
    new Parent() {ParentID = "parentID1", Children = new List<Child>() {new Child() {ChildID = "childID1"},new Child() {ChildID = "childID2"}}},
    new Parent() {ParentID = "parentID2", Children = new List<Child>() {new Child() {ChildID = "childID3"},new Child() {ChildID = "childID4"}}}
    };
IEnumerable<string> enumerable = xElements.Select(s => s.ToString());


IEnumerable<XElement> xElements = list.Select(s => new XElement("Mapping", new XAttribute("ID", s.ParentID), s.Children.Select(t => new XAttribute("ChildID", t.ChildID))));
IEnumerable<string> enumerable = xElements.Select(s => s.ToString());
var @join = string.Join(Environment.NewLine, enumerable);

这是因为它会使用Select 的重载,它使用当前对象的索引:

var list = new List<Parent>
{
    new Parent
    {
        ParentID = "parentID1",
        Children = new List<Child> {new Child {ChildID = "childID1"}, new Child {ChildID = "childID2"}}
    },
    new Parent
    {
        ParentID = "parentID2",
        Children = new List<Child> {new Child {ChildID = "childID3"}, new Child {ChildID = "childID4"}}
    }
};

IEnumerable<XElement> xElements =
    list.Select(
        s =>
            new XElement("Mapping", new XAttribute("ID", s.ParentID),
                s.Children.Select((t, u) => new XAttribute(string.Format("ChildID_{0}", u), t.ChildID))));
var @join = string.Join(Environment.NewLine,xElements);

结果:不是你所期待的,对吧?

<Mapping ID="parentID1" ChildID_0="childID1" ChildID_1="childID2" />
<Mapping ID="parentID2" ChildID_0="childID3" ChildID_1="childID4" />

为什么我使用了这个重载?

因为父级有一个子级列表,而第一个代码适用于一个子级,但不适用于许多子级。

结论:

不确定您要达到的目标,

为什么不保持对象的结构不变呢?

【讨论】:

  • 我正在尝试从上述对象中组织的数据中获取我发布的示例 XML,本质上是一个 (ParentID, ChildID) 映射。不幸的是,更改数据结构或 XML 格式都不是一种选择。
  • 好的,但是正如我在回答中解释的那样,保持这样的结构不适用于多个孩子,或者您是否期望生成许多映射,例如 Parent1 -> Child1, Parent1 -> Child2 作为输出?
  • 有效地展平该层次结构并获取所有行:我在原始帖子中包含了一个示例作为编辑。
  • 好的,看看我的编辑。
  • 感谢您的帮助,尽管我仍然不明白发生了什么,但我来这里是为了想办法不赢得本月的问题。
猜你喜欢
  • 2022-01-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 1970-01-01
  • 2020-05-29
  • 1970-01-01
相关资源
最近更新 更多