TextBox,内容为XML文本,点击某个位置后获取该文本所在完整路径

51Crack 2016-02-03 05:45:14
可能内容有相同,比如:TextBox中点击第2个111的位置,能够返回Main1/Child2/Child2.1,点击其它地方,返回空

<ROOT>
<Main1>
<Child1>
<Child1.1>111<</Child1.1>
<Child1.2>222<</Child1.1>
</Child1>
<Child2>
<Child2.1>111<</Child1.1>
<Child2.2>222<</Child1.1>
</Child2>
</Main1>
<Main2>
</Main2>
</ROOT>
...全文
156 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
51Crack 2016-02-04
  • 打赏
  • 举报
回复
引用 2 楼 Forty2 的回复:
这个简单的用‘状态机’加上简单的回溯就可以了。 当没有<![CDATA[ ]]>的时候,'<'和‘>’不能出现在字符串里,因此,直接寻找'<'和‘>'字符就可以了。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        TextBox textBox = new TextBox() { Multiline = true, Dock = DockStyle.Fill };
        textBox.Click += delegate
        {
            this.Text = GetPath(textBox.Text, textBox.SelectionStart);
        };
        textBox.Text = 
@"<ROOT>
<Main1>
<Child1>
    <Child1.1>111</Child1.1>
    <Child1.2>222</Child1.1>
</Child1>
<Child2>
    <Child2.1>aaa</Child1.1>
    <Child2.2>222</Child1.1>
</Child2>
</Main1>
<Main2>
</Main2>
</ROOT>";
        this.Controls.Add(textBox);
    }

    public static string GetPath(string xml, int position)
    {
        Stack<string> pathStack = new Stack<string>();
        Stack<char> textStack = new Stack<char>();

        int debt = 0;
        bool closePending = false;
        for (int i = Math.Min(position, xml.Length - 1); i >= 0; i--)
        {
            switch (xml[i])
            {
                case '>':
                    textStack.Clear();  
                    break;
                case '<':
                    if (closePending)
                    {
                        debt++;
                    }
                    else
                    {
                        if (debt > 0) 
                        {
                            debt--; 
                        }
                        else
                        {
                            pathStack.Push(new string(textStack.ToArray()));
                            textStack.Clear();
                        }
                    }
                    break;
                default:
                    textStack.Push(xml[i]);
                    break;
            }
            closePending = xml[i] == '/';
        }
        return string.Join("/", pathStack);
    }
}
Justin-Liu 2016-02-04
  • 打赏
  • 举报
回复
看起来像通过NODE取XPATH
Forty2 2016-02-03
  • 打赏
  • 举报
回复
这个简单的用‘状态机’加上简单的回溯就可以了。 当没有<![CDATA[ ]]>的时候,'<'和‘>’不能出现在字符串里,因此,直接寻找'<'和‘>'字符就可以了。

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        TextBox textBox = new TextBox() { Multiline = true, Dock = DockStyle.Fill };
        textBox.Click += delegate
        {
            this.Text = GetPath(textBox.Text, textBox.SelectionStart);
        };
        textBox.Text = 
@"<ROOT>
<Main1>
<Child1>
    <Child1.1>111</Child1.1>
    <Child1.2>222</Child1.1>
</Child1>
<Child2>
    <Child2.1>aaa</Child1.1>
    <Child2.2>222</Child1.1>
</Child2>
</Main1>
<Main2>
</Main2>
</ROOT>";
        this.Controls.Add(textBox);
    }

    public static string GetPath(string xml, int position)
    {
        Stack<string> pathStack = new Stack<string>();
        Stack<char> textStack = new Stack<char>();

        int debt = 0;
        bool closePending = false;
        for (int i = Math.Min(position, xml.Length - 1); i >= 0; i--)
        {
            switch (xml[i])
            {
                case '>':
                    textStack.Clear();  
                    break;
                case '<':
                    if (closePending)
                    {
                        debt++;
                    }
                    else
                    {
                        if (debt > 0) 
                        {
                            debt--; 
                        }
                        else
                        {
                            pathStack.Push(new string(textStack.ToArray()));
                            textStack.Clear();
                        }
                    }
                    break;
                default:
                    textStack.Push(xml[i]);
                    break;
            }
            closePending = xml[i] == '/';
        }
        return string.Join("/", pathStack);
    }
}
  • 打赏
  • 举报
回复
我怎么觉得这个应该用tree来展示!

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧