简体   繁体   English

附加XML元素列表

[英]Append an XML element list

I'm trying to reformat my XML code so it's easier to read. 我正在尝试重新格式化XML代码,以便于阅读。 At the moment it looks like this: 现在看起来像这样:

 <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>

However what I want it look like is this: 但是我想要的样子是这样的:

 <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>

Ok, rubbish example but I hope you get the jist; 好的,垃圾的例子,但我希望你能理解。 I want all of my values like tag and local position etc to be a child of the screen name. 我希望我的所有值(例如标签和本地位置等)都是屏幕名称的子代。 Now I know that to do this it would normally be the following call: 现在我知道要执行此操作通常是以下调用:

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

But, I've set my XML creation code in a list that is held in one class and populated in another. 但是,我将XML创建代码设置在一个类中包含的列表中,并填充到另一个类中的列表中。 It looks like this: 看起来像这样:

Generate 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);
    }

Then to fill this out, I'm doing the following in a derived class: 然后填写此内容,我在派生类中进行以下操作:

  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);
        }

} }

Now my real question is how do I append my _screenTag element so that its a child of my screen name when I've set up the creation of my xml in a list in a different class? 现在,我真正的问题是,当我在其他类的列表中创建xml时,如何附加_screenTag元素,使其成为屏幕名称的子级?

It seems to me that the difficulty that you have is a schema mismatch between your c# data structure and the desired XML data structure. 在我看来,您遇到的困难是c#数据结构与所需XML数据结构之间的架构不匹配。

ie Your list is a 'flat' structure, but the desired XML has nesting. 即您的列表是一个“扁平”结构,但是所需的XML具有嵌套。

Ideally you should refactor your code so that the two are more similar, you could create ac# model object for Display_Settings and then add child properties to that class as appropriate. 理想情况下,您应该重构代码,使两者更相似,可以为Display_Settings创建ac#模型对象,然后根据需要将子属性添加到该类。 This might allow you to use .Net built in XML serialisation instead of having to hand-crank it as you are now. 这可能使您可以使用内置于XML序列化中的.Net,而不必像现在一样手动操作它。

Alternatively, if you are stuck with the manual XML creation, you could use the inherent support for tree structures that is in the XmlElement class, ie use the ChildNodes property: http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.childnodes.aspx 另外,如果您不愿手工创建XML,则可以使用XmlElement类中对树结构的固有支持,即使用ChildNodes属性: http : //msdn.microsoft.com/zh-cn/library/ system.xml.xmlnode.childnodes.aspx

You can insert the desired tag anywhere in the XML by follows, 您可以按照以下步骤在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);

How about this? 这个怎么样? (using LinqToXml) (使用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();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM