1

我的 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>

我的困境是,maintextbox 正在生成实际的字符串“ 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”和“but”也发生了变化。当这种变化发生时,我不必重写代码和重新编译程序。我只会在 xml 中进行更改。

4

2 回答 2

2

您的解决方案中的 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"。如果是,那么它将是orand或其他连接词
  • 最后,我们检查所有文本框是否匹配质量字符串部分中的文本框名称。如果匹配,则我们将部分替换为文本框中的文本
  • 我们加入部分以获得结果字符串

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

var listFurniture = xml.Descendants("Quality") 
                       .Select(q => (string)q)
                       .ToList();
于 2013-01-18T07:18:29.960 回答
1

更新:

因为我收到了一条评论来解释一下代码;我会稍微解释一下。

首先,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();
于 2013-01-18T00:08:17.540 回答