1

我正在尝试重新格式化我的 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);
        }

}

现在我真正的问题是如何附加我的 _screenTag 元素,以便当我在不同类的列表中设置我的 xml 的创建时它是我的屏幕名称的子元素?

4

3 回答 3

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);
于 2013-05-31T09:31:46.433 回答
1

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

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

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

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

于 2013-05-31T09:22:36.470 回答
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();
于 2013-05-31T09:16:49.197 回答