/home/home/room1/home/room1/subroom/home/room2/home/room2/miniroom/home/room2/bigroom/home/room2/hugeroom/home/room3
到一个xml文件.我已经尝试使用liNQ to XML来做到这一点,但我最终感到困惑,不知道该怎么做.任何帮助深表感谢!
编辑:
我希望XML文件看起来像这样:
<home> <room1> <subroom>This is a subroom</subroom> </room1> <room2> <miniroom>This is a miniroom</miniroom> <bigroom>This is a bigroom</bigroom> <hugeroom>This is a hugeroom</hugeroom> </room2> <room3></room3></home>
如果标签(“这是一个子房间等”)里面的文字是可选的,但是真的很棒!
解决方法 好的哥们,这是一个解决方案.几个笔记和解释.
您的文本结构可以分成行,然后通过斜杠再次分成XML节点的名称.如果以这种方式考虑文本,就会得到一个列为“列”的“行”列表
名.
/home
首先,第一行/ home是XML的根;我们可以摆脱它,只需用该名称创建和Xdocument对象作为根元素;
var xDoc = new Xdocument("home");
当然我们不想硬编码,但这只是一个例子.现在,关于真正的工作:
/home/room1//home/room1/bigroometc...
作为列表< T>那么它会是这样的
myList = new List<List<string>>();... [ add the items ]myList[0][0] = homemyList[0][1] = room1myList[1][0] = homemyList[1][1] = room1myList[1][2] = bigroom
因此,我们可以做的是获得上述结构,多次使用string.Split()将文本首先分解为行,然后分成每行的部分,最后使用多维数组样式List< T>包含List< T>对象,在本例中为List< List< string>>.
首先让我们创建容器对象:
var possibleNodes = new List<List<string>>();
接下来,我们应该拆分线.让我们调用包含文本的变量“text”.
var splitlines = text .Split(new string[] { Environment.Newline },StringSplitoptions.RemoveEmptyEntrIEs) .ToList();
这给了我们一个列表,但我们的线路仍未分解.让我们用斜杠(/)字符再次拆分它们.这是我们构建节点名称的地方.我们可以在ForEach中执行此 *** 作,只需添加到可能的节点列表中:
splitlines.ForEach(l => possibleNodes.Add(l .Split(new char[] { '/' },StringSplitoptions.RemoveEmptyEntrIEs) .ToList() ));
现在,我们需要知道XML的DEPTH.您的文字显示将有3个深度节点.节点深度是任何一个给定节点行的最大深度,现在存储在List< List< string>> ;;我们可以使用.Max()方法来获取:
var nodeDepth = possibleNodes.Max(n => n.Count);
最后的设置步骤:我们不需要第一行,因为它只是“home”,它将是我们的根节点.我们可以创建一个Xdocument对象并将其作为第一行用作Root的名称:
// Create the root nodeXdocument xDoc = new Xdocument(new XElement(possibleNodes[0][0]));// We don't need it anymorepossibleNodes.RemoveAt(0);
好的,这是实际工作发生的地方,让我解释一下规则:
>我们需要循环遍历外部列表,并遍历每个内部列表.
>我们可以使用列表索引来了解要添加的节点或要忽略的名称
>我们需要保持层次结构正确而不是重复节点,并且一些Xlinq在这里有所帮助
循环 – 请参阅注释以获取详细说明:
// This gets us looPing through the outer nodesfor (var i = 0; i < possibleNodes.Count; i++) { // Here we go "sIDeways" by going through each inner List (each broken down line of the text) for (var ii = 1; ii < nodeDepth; ii++) { // Some lines have more depth than others,so we have to check this here since we are looPing on the maximum if (ii < possibleNodes[i].Count) { // Let's see if this node already exists var existingNode = xDoc.Root.Descendants().FirstOrDefault(d => d.name.Localname == (possibleNodes[i][ii])); // Let's also see if a parent node was created in the prevIoUs loop iteration. // This will tell us whether to add the current node at the root level,or under another node var parentNode = xDoc.Root.Descendants().FirstOrDefault(d => d.name.Localname == (possibleNodes[i][ii - 1])); // If the current node has already been added,we do nothing (this if statement is not entered into) // Otherwise,existingNode will be null and that means we need to add the current node if (null == existingNode) { // Now,use parentNode to decIDe where to add the current node if (null == parentNode) { // The parent node does not exist; therefore,the current node will be added to the root node. xDoc.Root.Add(new XElement(possibleNodes[i][ii])); } else { // There IS a parent node for this node! // Therefore,we must add the current node to the parent node // (remember,parent node is the prevIoUs iteration of the inner for loop on nodeDepth ) var newNode = new XElement(possibleNodes[i][ii]); parentNode.Add(newNode); // Add "this is a" text (bonus!) -- only adding this text if the current node is the last one in the List. if (possibleNodes[i].Count -1 == ii) { newNode.Add(new XText("This is a " + newNode.name.Localname)); } } } } }}
这里的优点是此代码可以与任意数量的节点一起使用并构建您的XML.
为了检查它,Xdocument有一个漂亮的.ToString()覆盖实现,只是吐出它所持有的所有XML,所以你要做的就是:
Console.Write(xDoc.ToString());
而且,你会得到这个结果:
(注意我添加了一个测试节点,以确保它适用于超过3个级别)
下面,您将找到包含测试文本等的整个程序,作为一个有效的解决方案:
using System;using System.Collections.Generic;using System.linq;using System.Xml.linq;namespace XmlFromTextString{ class Program { static voID Main(string[] args) { // This simulates text from a file; note that it must be flush to the left of the screen or else the extra spaces // add unneeded nodes to the Lists that are generated; for simplicity of code,I chose not to implement clean-up of that and just // ensure that the string literal is not indented from the left of the Visual Studio screen. string text =@"/home/home/room1/home/room1/subroom/home/room2/home/room2/miniroom/home/room2/test/thetest/home/room2/bigroom/home/room2/hugeroom/home/room3"; var possibleNodes = new List<List<string>>(); var splitlines = text .Split(new string[] { Environment.Newline },StringSplitoptions.RemoveEmptyEntrIEs) .ToList(); splitlines.ForEach(l => possibleNodes.Add(l .Split(new char[] { '/' },StringSplitoptions.RemoveEmptyEntrIEs) .ToList() ) ); var nodeDepth = possibleNodes.Max(n => n.Count); // Create the root node Xdocument xDoc = new Xdocument(new XElement(possibleNodes[0][0])); // We don't need it anymore possibleNodes.RemoveAt(0); // This gets us looPing through the outer nodes for (var i = 0; i < possibleNodes.Count; i++) { // Here we go "sIDeways" by going through each inner List (each broken down line of the text) for (var ii = 1; ii < nodeDepth; ii++) { // Some lines have more depth than others,so we have to check this here since we are looPing on the maximum if (ii < possibleNodes[i].Count) { // Let's see if this node already exists var existingNode = xDoc.Root.Descendants().FirstOrDefault(d => d.name.Localname == (possibleNodes[i][ii])); // Let's also see if a parent node was created in the prevIoUs loop iteration. // This will tell us whether to add the current node at the root level,or under another node var parentNode = xDoc.Root.Descendants().FirstOrDefault(d => d.name.Localname == (possibleNodes[i][ii - 1])); // If the current node has already been added,we do nothing (this if statement is not entered into) // Otherwise,existingNode will be null and that means we need to add the current node if (null == existingNode) { // Now,use parentNode to decIDe where to add the current node if (null == parentNode) { // The parent node does not exist; therefore,the current node will be added to the root node. xDoc.Root.Add(new XElement(possibleNodes[i][ii])); } else { // There IS a parent node for this node! // Therefore,we must add the current node to the parent node // (remember,parent node is the prevIoUs iteration of the inner for loop on nodeDepth ) var newNode = new XElement(possibleNodes[i][ii]); parentNode.Add(newNode); // Add "this is a" text (bonus!) -- only adding this text if the current node is the last one in the List. if (possibleNodes[i].Count -1 == ii) { newNode.Add(new XText("This is a " + newNode.name.Localname)); // For the same default text on all child-less nodes,us this: // newNode.Add(new XText("This is default text")); } } } } } } Console.Write(xDoc.ToString()); Console.ReadKey(); } }}总结
以上是内存溢出为你收集整理的c# – 基于文本树创建XML全部内容,希望文章能够帮你解决c# – 基于文本树创建XML所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)