2013-05-31 5 views
1

Я пытаюсь переформатировать свой 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); 
     } 

}

Теперь моя реальная Вопрос в том, как добавить свой элемент _screenTag, чтобы его дочерний элемент моего имени экрана, когда я создал создание моего xml в списке в другом классе?

+0

XML, вы ожидаете, содержит в два раза ' 1' – I4V

+0

Да я вручную Rote, что, чтобы показать, что я пытаюсь сделать. Спасибо, что указали на это. – N0xus

+0

Теперь у вас есть два закрывающих тега для 'ScreenName' – I4V

ответ

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(); 
+1

Что это должно заменить? – N0xus

+0

@ N0xus Это совершенно новый код с использованием LinqToXml. 'newxml' - это xml, который вы хотите. Как насчет того, чтобы попробовать? – I4V

1

Мне кажется, что трудности, которые у вас есть несоответствие схемы между C# структуры данных и требуемой структуры данных XML.

т. Е. Ваш список является «плоской» структурой, но желаемый XML имеет гнездование.

В идеале вы должны реорганизовать свой код так, чтобы эти два типа были более похожими, вы могли бы создать объект модели C# для Display_Settings, а затем добавить соответствующие свойства для этого класса. Это может позволить вам использовать .Net, встроенный в сериализацию XML, вместо того, чтобы вручную запускать его так, как вы сейчас.

В качестве альтернативы, если вы застряли с созданием ручной XML, вы можете использовать присущую поддержку древовидных структур, которая находится в классе XMLElement, т.е. использовать свойство ChildNodes: http://msdn.microsoft.com/en-us/library/system.xml.xmlnode.childnodes.aspx

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); 
Смежные вопросы