c# – 基于文本树创建XML

c# – 基于文本树创建XML,第1张

概述我需要从这样的列表中去: /home/home/room1/home/room1/subroom/home/room2/home/room2/miniroom/home/room2/bigroom/home/room2/hugeroom/home/room3 到一个xml文件.我已经尝试使用LINQ to XML来做到这一点,但我最终感到困惑,不知道该怎么做.任何帮助深表感谢! 编辑 我需要从这样的列表中去:

/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>&gt ;;我们可以使用.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所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1218783.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存