控件作为xml值

本文关键字:xml 控件 | 更新日期: 2023-09-27 17:53:58

我有这个例子代码在我的c# win表单…

List<string> listFurniture = new List<string>();
XDocument xml = XDocument.Load(Application.StartupPath + @"'Furniture.xml");
foreach (XElement quality in xml.Descendants("Quality"))
    listFurniture.Add(quality.Value);
maintextbox.Text = listFurniture[0];

…这个例子xml

<Furniture>
  <Table>
    <Quality>textbox1.Text + "and" + textbox2.Text + "but" + textbox3.Text</Quality>   
    ...
  </Table>  
</Furniture>

我的困境是,主文本框正在产生实际的字符串"textbox1.Text",而不是textbox1的值。

我希望xml值被读取为:

maintextbox.Text = textbox1.Text + "and" + textbox2.Text + "but" + textbox3.Text;

不是:

maintextbox.Text = "textbox1.Text + "and" + textbox2.Text + "but" + textbox3.Text";

我尝试使用文本文件以及StreamReader,我得到了相同的结果。

以这种方式编码我的项目的原因是因为文本框的顺序发生了变化,"and"answers"but"也发生了变化。当这种变化发生时,我不需要重写代码和重新编译程序。我只需要修改xml

控件作为xml值

在您的解决方案中使用xml解析是没问题的。你需要的是Quality字符串的处理。

string[] parts = quality.Split('+');
Regex regex = new Regex(@"^""(.*)""$");
var textBoxes = Controls.OfType<TextBox>().ToList();
for (int i = 0; i < parts.Length; i++)
{
    string part = parts[i].Trim();
    var match = regex.Match(part);
    if (match.Success)
    {
        parts[i] = match.Groups[1].Value;
        continue;
    }
    var textBox = textBoxes.FirstOrDefault(tb => tb.Name + ".Text" == part);
    if (textBox != null) // possibly its an error if textbox not found
        parts[i] = textBox.Text; 
}    
mainTextBox.Text = String.Join(" ", parts);

这里发生了什么:

  • 我们将质量字符串按+字符拆分得到字符串部分数组
  • 使用正则表达式,我们验证部分是否看起来像引号"something"中的东西。如果是,则为or, and或其他连接词
  • 最后,我们检查所有文本框是否匹配质量字符串部分的文本框名称。如果匹配,则用文本框
  • 中的文本替换part。
  • 我们连接部件以获得结果字符串

顺便说一句,你可以在一行中解析Xml:

var listFurniture = xml.Descendants("Quality") 
                       .Select(q => (string)q)
                       .ToList();

更新:

因为我收到了一个注释来解释代码;我来解释一下。

首先,XML作为一种语言是为结构而设计的。那结构和安逸;提供了在语言或应用程序之间无缝快速解析数据的灵活性和功能。你原来的问题说,你的文本框正在产生一个字符串值你的代码textbox.text

XML需要结构化;一个示例结构是:

<Furniture>
     <Table>
         <Color> Red </Color>
         <Quality> 10 </Quality>
         <Material> Wood </Material>
      </Table>
</Furniture>

所以如果你要读你的XML,它会找到root标签。所有其他组件都是nodes。需要对这些节点进行索引或抽取,以获得您希望在文本框中表示的适当相关性。

这就是这段代码所做的;我将详细说明每一步。

// String you will format with the XML Structure.
StringBuilder output = new StringBuilder();

下一部分内容如下:

// Create an XML Reader, by wrapping it in the 'using' it will ensure once your done the object is disposed of.  Rather then leaving the connection to your document open.
using (XmlReader reader = XmlReader.Create(new StringReader(xmlString)))
{
       // We will read our document to the following; hold to that attribute.  The attribute is identifying the node and all of the child elements that reside within it: So in our case Table.
       reader.ReadToFollowing("Table");
       reader.MoveToFirstAttribute();
       string color = reader.Value;
       output.AppendLine("The color of the table " + color);
       // As you can see there isn't anything fancy here, it reads to our root node.  Then moves to the first child element.  Then it creates a string and appends it. Keep in mind we are using our StringBuilder so we are just appending to that structure.
       reader.ReadToFollowing("Material");
       output.AppendLine("The material: " + reader.ReadElementContentAsString());
       // Same result as we used earlier; just a different method to attain our value.
}
// Now we output our block.
OutputTextBlock.Text = output.ToString();

现在所有的数据都被压入一个字符串中,显然您也可以使用上面的代码和一个文本框来检索这些值。

这就是你如何正确地接收XML到你的应用程序;但是你之前提到了两件事。因此,听起来您试图使用文本框对文档进行物理写入,这可以通过XmlWriter完成。

但是你也一直收到你的文本框的原因是因为就文本框而言,textbox.text是与值相关联的。你的结构说明这个字符串是值。

为了实现你的目标;您将拥有一个将值写入文档的方法。然后另一个人去读它;

<Quality>Textbox1.Text</Quality>不允许文本框的值自动读取到您的文档和文本框。将字符串值赋给节点。在读取文档之前,您必须将这些值写入文档。

MSDN有如何正确解析数据的示例;希望我已经澄清了你遇到问题的一些原因。


更多的代码;直接来自MSDN:直接关闭MSDN:

StringBuilder output = new StringBuilder();
String xmlString =
        @"<?xml version='1.0'?>
        <!-- This is a sample XML document -->
        <Items>
          <Item>test with a child element <more/> stuff</Item>
        </Items>";
// Create an XmlReader
using (XmlReader reader = XmlReader.Create(new StringReader(xmlString)))
{
    XmlWriterSettings ws = new XmlWriterSettings();
    ws.Indent = true;
    using (XmlWriter writer = XmlWriter.Create(output, ws))
    {
        // Parse the file and display each of the nodes.
        while (reader.Read())
        {
            switch (reader.NodeType)
            {
                case XmlNodeType.Element:
                    writer.WriteStartElement(reader.Name);
                    break;
                case XmlNodeType.Text:
                    writer.WriteString(reader.Value);
                    break;
                case XmlNodeType.XmlDeclaration:
                case XmlNodeType.ProcessingInstruction:
                    writer.WriteProcessingInstruction(reader.Name, reader.Value);
                    break;
                case XmlNodeType.Comment:
                    writer.WriteComment(reader.Value);
                    break;
                case XmlNodeType.EndElement:
                    writer.WriteFullEndElement();
                    break;
            }
        }
    }
}
OutputTextBlock.Text = output.ToString();

StringBuilder output = new StringBuilder();
String xmlString =
    @"<bookstore>
        <book genre='autobiography' publicationdate='1981-03-22' ISBN='1-861003-11-0'>
            <title>The Autobiography of Benjamin Franklin</title>
            <author>
                <first-name>Benjamin</first-name>
                <last-name>Franklin</last-name>
            </author>
            <price>8.99</price>
        </book>
    </bookstore>";
// Create an XmlReader
using (XmlReader reader = XmlReader.Create(new StringReader(xmlString)))
{
    reader.ReadToFollowing("book");
    reader.MoveToFirstAttribute();
    string genre = reader.Value;
    output.AppendLine("The genre value: " + genre);
    reader.ReadToFollowing("title");
    output.AppendLine("Content of the title element: " + reader.ReadElementContentAsString());
}
OutputTextBlock.Text = output.ToString();