我尝试使用 XDocument 解析 xml 文件中的文本,但并非所有结果都如我所愿,为啥?

Posted

技术标签:

【中文标题】我尝试使用 XDocument 解析 xml 文件中的文本,但并非所有结果都如我所愿,为啥?【英文标题】:Im trying to parse text from xml file using XDocument but not all the results are as i wanted to be why?我尝试使用 XDocument 解析 xml 文件中的文本,但并非所有结果都如我所愿,为什么? 【发布时间】:2012-08-23 12:19:37 【问题描述】:

我有一个按钮点击事件:

private void button1_Click(object sender, EventArgs e)
        

            string fileName = @"d:\adilipman1937067724.xml";
            ParseAndDisplayXml(fileName);
        

以及功能:

private void ParseAndDisplayXml(string filename)
        
            XDocument document = XDocument.Load(filename);
            var list = document.Root.Elements("Message")
                .Select(
                e => new
                
                    Date = e.Attribute("Date").ToString(),
                    Time = e.Attribute("Time").ToString(),
                    Text = e.Attribute("Text").ToString()
                
                );
 string result="";
            foreach (var item in list)
            
               result += string.Format("Date--0,Time--1,Text--2", item.Date, item.Time, item.Text);


            
textBox1.Text = result;
        

日期和时间的结果是好的,但文本的结果是错误的。 这是文本的结果: 你好 我需要在文本中得到的只是你好 日期和时间的结果是:Date="31/01/2012" and Time="10:15:42"

问题在于获取文本。

那么当我运行程序时我在textBox1中得到了什么是一团糟:

Date--Date="31/01/2012",Time--Time="10:15:42",Text--הייDate--Date="31/01/2012",Time--Time= "10:15:55",Text--הייתה לי בעיה עם התוכנת ברקים אבל עכשיו הכל עובד.Date--Date="31/01/2012",Time-"8--Time="10:15: -מה השלב הבא ?Date--Date="31/01/2012",Time--Time="10:16:27",Text--אמרת ליבזמנו לחשב ממוצע של 1000 ערכים ? הכוונה 1000 ערכים בפריים ? כיברייתית256מספריתם?日期 - 日期=“31/01/2012”,时间 - 时间=“10:17:03”,文本 - לחשבמממוצעשל1000העיםםיםםיתהיםרהבהיורמה日期 - 日期=“31 /01/2012",Time--Time="10:17:10",Text--ז"א בפרייםDate--Date="31/01/2012",Time--Time="10:17:14" ,Text--לא בהיסטוגרמהDate--Date="31/01/2012",Time--Time="10:17:20",Text--בעזרת ההיסטוגרמהDate--Date="31/01/2012",Time- -time =“10:17:50”,文本 - תחשובלמשלשליךךךמהממממממממממממממממממממתהכלכליורמהDate-Date =“31/01/2012”,时间 - 时间=“10:18:08” ,文本 - בריתחשובתחשוביךךמוצאאתאתמספרהגבוהרותיורהתיור上臂,Time--Time="10:18:45",Text--ואז תכתוב פונקציהDate--Date="31/01/2012",Time--Time="10:18:54",Text--

而原来的xml文件内容例如是这样的:

<?xml version="1.0"?>
<?xml-stylesheet type='text/xsl' href='MessageLog.xsl'?>
<Log FirstSessionID="1" LastSessionID="2">
  <Message Date="31/01/2012" Time="10:15:42" DateTime="2012-01-31T08:15:42.467Z" SessionID="1">
    <From>
      <User FriendlyName="Chocolade"/>
    </From>
    <To>
      <User FriendlyName="adilipman@yahoo.com"/>
    </To>
    <Text Style="font-family:Segoe UI; color:#000000; ">היי</Text>
  </Message>
  <Message Date="31/01/2012" Time="10:15:55" DateTime="2012-01-31T08:15:55.097Z" SessionID="1">
    <From>
      <User FriendlyName="Chocolade"/>
    </From>
    <To>
      <User FriendlyName="adilipman@yahoo.com"/>
    </To>
    <Text Style="font-family:Segoe UI; color:#000000; ">הייתה לי בעיה עם התוכנת ברקים אבל עכשיו הכל עובד.</Text>
  </Message>
  <Message Date="31/01/2012" Time="10:15:58" DateTime="2012-01-31T08:15:58.897Z" SessionID="1">
    <From>
      <User FriendlyName="Chocolade"/>
    </From>
    <To>
      <User FriendlyName="adilipman@yahoo.com"/>
    </To>
    <Text Style="font-family:Segoe UI; color:#000000; ">מה השלב הבא ?</Text>
  </Message>
  <Message Date="31/01/2012" Time="10:16:27" DateTime="2012-01-31T08:16:27.775Z" SessionID="1">
    <From>
      <User FriendlyName="Chocolade"/>
    </From>
    <To>
      <User FriendlyName="adilipman@yahoo.com"/>
    </To>
    <Text Style="font-family:Segoe UI; color:#000000; ">אמרת לי בזמנו לחשב ממוצע של 1000 ערכים ? הכוונה 1000 ערכים בפריים ? כי בפריים יש 256 מספרים לא ?</Text>
  </Message>
</Log>

【问题讨论】:

【参考方案1】:

这是因为在您提供的 XML 文件中,Text 不是一个属性,而是Message子标签

您需要做的是选择您想要的子节点(例如使用node.SelectNodesnode.SelectSingleNode),然后获取它的文本值(node.InnerText)。

至于textBox1中的mess,需要在每一行后面加上\r\n(string.Format("...\r\n", ...)


好的,让我们看一下您的 XML 文件:如果有必要,您应该阅读一些内容,以对 XML 文件所包含的attributeselements 有基本的了解。

所以你的文件:有元素Message,它有attributes日期时间日期时间SessionID 。接下来,这个Message 元素有子节点FromToText,其中两个第一个没有属性,而第三个有样式属性和内部文本(&lt;Text&gt;&lt;/Text&gt; 标签之间的所有内容。

下面是XmlNode类的使用方法:

XmlDocument xml = new XmlDocument()
xml.Load("path_to_xml_file");

这里我们将整个 xml 文件加载到一个对象中。现在我们可以选择特定的节点:

XmlNodeList messages = xml.SelectNodes("/root/Message");

"/root/Message" 部分是 XPath,您可能想了解一下,它非常有用...

现在,我们文件中的所有Message 节点都在列表messages 中。我们可以迭代它:

foreach (XmlNode message in messages)
   ... 

我们可以获取每个节点的属性:

#msg is a XmlNode from messages list
#XmlNode.Attributes is a list of all attributes in given node
XmlNode dateAttribute = msg.Attributes.GetNamedItem("Date");

注意我们的属性本身是一个 XmlNode。如果节点中没有该属性,则为dateAttribute == null,否则,其值可通过dateAttribute.Value 访问。 我通常为此做辅助功能:

public static string GetStringAttribute(XmlNode node, string name, string defaultValue="")
    
        XmlNode attrNode = node.Attributes.GetNamedItem(name);
        if (attrNode == null)
            return defaultValue;
        else
            return attrNode.Value.Trim();
    

同样从我们的Message 节点,我们可以提取它的Text 部分:

XmlNode textNode = msg.SelectSingleNode("Text");
string textBetweenTags = textNode.InnerText;

我希望这能澄清一点,以了解 XML 文件是如何构建的,XPath 是什么以及如何使用它我推荐W3School。

我不会更正你所有的代码,但是使用它并记住在添加每一行后输入\r\n,你应该得到你想要的输出,祝你好运!

【讨论】:

你能告诉我吗,请举例说明如何在我的代码中使用 node.SelectNodes ?谢谢。 我可能用得太快了,因为您使用的是 XElement 类。因此我认为e.Element("Text").ToString() 就足够了。我自己解析 XML 文件使用 XMLNode 类和 SelectNodesSelectSingleNode 来获取元素 - 这些函数使用 xpath 在你正在处理的节点内找到所需的元素...... 没有 e.Element 没有做这项工作。然后告诉我如何使用 XMLNode ?谢谢。 我确实扩展了我的答案,我希望这会有所帮助。

以上是关于我尝试使用 XDocument 解析 xml 文件中的文本,但并非所有结果都如我所愿,为啥?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Xdocument 进行简单的 Xml 解析

使用XDocument.Load(xmlreader)方法?

无法使用 Xdocument 和 Linq 解析 xml 字符串

我已经在我的 SQL 数据库和 WPF 应用程序之间创建了一个连接,但我想使用 XML 文件和 XDocument 来连接它们

XDocument 读取具有名称空间的根元素的 XML 文件

使用C#中的XDocument对DataGridView进行XML查询