附加XML元素列表

时间:2013-05-31 08:52:22

标签: c# xml

我正在尝试重新格式化我的XML代码,以便更容易阅读。目前它看起来像这样:

 <Settings>
  <Display_Settings>
    <ScreenName Name="1">1</ScreenName>
    <ScreenTag Tag="1">1</ScreenTag>
    <LocalPosition X="1" Y="1" Z="1">0.000, 0.000, 0.000</LocalPosition>
    <Width Width="0.000">0.000</Width>
    <Height Height="0.000">0.000</Height>
  </Display_Settings>
</Settings>

然而我想要的是这样:

 <Settings>
      <Display_Settings>
        <ScreenName Name="1">1
                 <ScreenTag Tag="1">1</ScreenTag>
                 <LocalPosition X="1" Y="1" Z="1">0.000, 0.000, 0.000</LocalPosition>
                 <Width Width="0.000">0.000</Width>
                 <Height Height="0.000">0.000</Height>
        </ScreenName>
      </Display_Settings>
 </Settings>

好的,垃圾示例,但我希望你得到这个小说;我希望我的所有值,如标记和本地位置等都是屏幕名称的子项。现在我知道要做到这一点通常是以下的电话:

 XmlNode _rootNode; // in the above i'll have set this to be Display_Settings
 _rootNode.AppendChild(_screenTag);

但是,我已将我的XML创建代码设置在一个列表中,该列表保存在一个类中并填充在另一个类中。它看起来像这样:

生成XML

  public HV_WriteXML()
    {
        //root node
        _rootNode = _xmlDoc.CreateElement("InMo_Settings");
        _xmlDoc.AppendChild(_rootNode);

        _userNode = _xmlDoc.CreateElement("Display_Settings");
        _rootNode.AppendChild(_userNode);
    }

    public void GenereateSettingsFile(List<Node> nodeList, string filePath)
    {

        _rootNode.RemoveChild(_userNode);

        _userNode = _xmlDoc.CreateElement("Display_Settings");
        _rootNode.AppendChild(_userNode);

        foreach (Node n in nodeList)
        {
            foreach (XmlElement e in n.GenerateXML(_xmlDoc))
            {
                _userNode.AppendChild(e);
            }
        }
        _xmlDoc.Save(filePath);
    }

然后为了填补这一点,我在派生类中执行以下操作:

  public override List<XmlElement> GenerateXML(XmlDocument _xmlDoc)
    {
        List<XmlElement> elementList = new List<XmlElement>();



         if (nodeDictionary.ContainsKey("Name "))
         {
            XmlElement _screenName = _xmlDoc.CreateElement("ScreenName");
            _screenName.SetAttribute("Name", (string)nodeDictionary["Name "].value);
            _screenName.InnerText = (string)nodeDictionary["Name "].value;
            elementList.Add(_screenName);
         }

        if (nodeDictionary.ContainsKey("Tag"))
        {
            XmlElement _screenTag = _xmlDoc.CreateElement("ScreenTag");
            _screenTag.SetAttribute("Tag", (string)nodeDictionary["Tag"].value);
            _screenTag.InnerText = (string)nodeDictionary["Tag"].value;

            elementList.Add(_screenTag);
        }

}

现在我真正的问题是,当我在另一个类的列表中设置我的xml创建时,如何附加我的_screenTag元素以使其成为我的屏幕名称的子项?

3 个答案:

答案 0 :(得分:1)

在我看来,您遇到的困难是您的c#数据结构与所需的XML数据结构之间的模式不匹配。

即。您的列表是一个“扁平”结构,但所需的XML已嵌套。

理想情况下,您应该重构代码以使两者更相似,您可以为Display_Settings创建一个c#模型对象,然后根据需要将子属性添加到该类。这可能允许您使用.Net内置的XML序列化,而不必像现在一样手动操作它。

或者,如果您不熟悉手动创建XML,则可以使用XmlElement类中树结构的固有支持,即使用ChildNodes属性:http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.childnodes.aspx

答案 1 :(得分:1)

您可以按照以下方式在XML中的任何位置插入所需的标记

//Get Display_Settings node
XmlNode displaySettingsNode = xmlDoc.SelectSingleNode(@"Settings/Display_Settings");
//Get LocalPosition node
XmlNode screenNameNode = xmlDoc.SelectSingleNode(@"Settings/Display_Settings/LocalPosition");
//Create Screen Tag
XmlElement screenTag = xmlDoc.CreateElement("ScreenTag");
screenTag.SetAttribute("Tag", (string)nodeDictionary["Tag"].value);
screenTag.InnerText = (string)nodeDictionary["Tag"].value;
//Insert Screen Tag node in desired location
displaySettingsNode.InsertBefore(screenTag, screenNameNode);

答案 2 :(得分:0)

这个怎么样? (使用LinqToXml)

var xDoc = XDocument.Parse(xmlstring); //or XDocument.Load(filename)

var elems = xDoc.Descendants("Display_Settings")
                .First()
                .Elements()
                .Where(e => e.Name.LocalName != "ScreenName")
                .ToList();

elems.ForEach(e => e.Remove());

xDoc.Descendants("ScreenName").First().Add(elems);

var newxml = xDoc.ToString();