如何从 xmlnodelist 获取 xml 节点
Posted
技术标签:
【中文标题】如何从 xmlnodelist 获取 xml 节点【英文标题】:How do i get xml nodes from the xmlnodelist 【发布时间】:2015-02-17 07:42:14 【问题描述】:我想获取我的表中称为数据的子节点列表。我已经设法获得值节点并循环抛出每个。现在我想对我的评论标签中的节点做同样的事情。我不知道如何获取评论标签中的节点(字体、日期戳和评论)。
<data name="Exit_Button" xml:space="preserve">
<value>Exit Finger Enrolment</value>
<comment>[Font]Regular[/Font][DateStamp]2014/012/01 00:00:00[/DateStamp] [Comment] this is a comment.!![/Comment]</comment>
我这样做是为了价值,它正在工作
XmlDocument _doc = new XmlDocument();
_doc.Load(outputFilePath);
string xmlcontents = _doc.InnerXml;
XmlNodeList _value = _doc.GetElementsByTagName("data");
foreach( XmlNode x in _value)
XmlNodeList y = x.ChildNodes;
for(int i = 0; i < y.Count; i++)
XmlNode z = y.Item(i);
if (z.Name.Contains("value"))
【问题讨论】:
这些不是 xml 节点。您必须解析comment
节点内容...
您能否向我们提供一组工作的 xml 示例数据和您的代码,以便我们了解您遇到的问题。
【参考方案1】:
如果这是你的 xml:
<?xml version="1.0" encoding="utf-8"?>
<data name="Exit_Button" xml:space="preserve">
<value>Exit Finger Enrolment</value>
<comment>[Font]Regular[/Font][DateStamp]2014/012/01 00:00:00[/DateStamp] [Comment] this is a comment.!![/Comment]</comment>
</data>
然后我像这样提取你的节点:
var root = XElement.Load(@"Path/to/your/file");
var result = root.Elements("comment").FirstOrDefault().Value;
为了获取标签之间的值,我从Dmitry Bychenko借了一个解决方案:
public static class Extensions
public static string ParseFromString(this string source, string start, string end)
int From = source.IndexOf(start) + start.Length;
int To = source.LastIndexOf(end);
string result = source.Substring(From, To - From);
return result;
并像这样使用它:
var font = result.ParseFromString("[Font]", "[/Font]");
var DateStamp = result.ParseFromString("[DateStamp]","[/DateStamp]");
var comment = result.ParseFromString("[Comment]","[/Comment]");
【讨论】:
这是我加载文件的方式,我不知道你是如何加载文件的【参考方案2】:要完成这项工作,您可以像这样形成一个聚合:
public class ResxFile
#region fields
private XDocument doc; //this is the aggregate
private IResxFileDataNode[] nodes;
#endregion
#region properties
public IResxFileDataNode[] DataNodes get return nodes;
#endregion
#region construction
//private constructor to avoid missuse of the class
private ResxFile(string path)
this.doc = XDocument.Load(path);
//use this instead
public static ResxFile Load(string path)
ResxFile result = new ResxFile(path);
result.CreateDataNodes();
return result;
#endregion
#region methods
private void CreateDataNodes()
this.nodes = doc.Descendants("data").Select(n => new ResxFileDataNode(n)).ToArray();
public void Save(string path)
this.doc.Save(path);
#endregion
public interface IResxFileDataNode : INotifyPropertyChanged
string Name get; //readonly field
string Value get; set; //this you can edit
string Font get; set; // i'd bind this to a combobox with all possible values
string DateStamp get; //i assume this is readonly and will be set to the current time once you update the fields
string Comment get; set;
public class ResxFileDataNode : IResxFileDataNode
#region fields
private static readonly Regex fontRegex = new Regex(@"(?<=\[Font\]).*?(?=\[/Font\])");
private static readonly Regex dateRegex = new Regex(@"(?<=\[DateStamp\]).*?(?=\[/DateStamp\])");
private static readonly Regex commentRegex = new Regex(@"(?<=\[Comment\]).*?(?=\[/Comment\])");
private static readonly string dateTimeFormat = "yyyy/dd/MM HH:mm:ss";
private XElement node; //this is the aggregate
private XElement valueNode;
private XElement commentNode;
private string name;
private string value;
private string font;
private DateTime dateTime;
private string comment;
#endregion
#region properties
public string Name
get return this.name;
public string Value
get
return this.value;
set
this.value = value;
valueNode.Value = this.value;
UpdateTimeStamp();
OnPropertyChanged("Value");
public string Font
get
return this.font;
set
this.font = value;
UpdateTimeStamp();
OnPropertyChanged("Font");
public string DateStamp
get return this.dateTime.ToString(dateTimeFormat);
public string Comment
get
return this.comment;
set
this.comment = value;
UpdateTimeStamp();
OnPropertyChanged("Comment");
#endregion
#region construction
public ResxFileDataNode(XElement dataNode)
this.node = dataNode;
this.valueNode = dataNode.Element("value");
this.value = this.valueNode.Value;
this.commentNode = dataNode.Element("comment");
this.name = dataNode.Attribute("name").Value;
this.comment = commentRegex.Match(this.commentNode.Value).Value;
this.font = fontRegex.Match(this.commentNode.Value).Value;
DateTime d;
if (DateTime.TryParseExact(dateRegex.Match(this.commentNode.Value).Value, dateTimeFormat, CultureInfo.InvariantCulture, DateTimeStyles.None, out d))
this.dateTime = d;
#endregion
#region methods
private void OnPropertyChanged(string propertyName)
PropertyChanged(this,new PropertyChangedEventArgs(propertyName));
private void UpdateTimeStamp()
this.dateTime = DateTime.Now;
UpdateCommentNode();
OnPropertyChanged("DateStamp");
private void UpdateCommentNode()
this.commentNode.Value = string.Format("[Font]0[/Font][DateStamp]1[/DateStamp][Comment]2[/Comment]", this.font.ToString(), this.dateTime.ToString(dateTimeFormat,CultureInfo.InvariantCulture), this.comment);
#endregion
#region events
public event PropertyChangedEventHandler PropertyChanged = delegate ;
#endregion
并将其与 datagridview 的绑定一起使用:
public partial class Form1 : Form
private ResxFile file;
public Form1()
InitializeComponent();
private void btnLoad_Click(object sender, EventArgs e)
file = ResxFile.Load("XMLFile1.xml"); //open a openfiledialog here to get the actual filename
var source = new BindingSource(file.DataNodes, null);
dataGridView1.DataSource = source;
private void btnSave_Click(object sender, EventArgs e)
file.Save("XMLFile1.xml"); //open a savefiledialog here to get the actual filename
【讨论】:
请注意,我不知道实际的时间格式是怎样的......如果我搞砸了更改这一行:private static readonly string dateTimeFormat = "yyyy/dd/MM HH:mm:ss"; 【参考方案3】:您的<comment>...</comment>
以一个特殊的XmlNode
类型结束,称为XmlElement
。因此,一旦你得到正确的XmlElement
,即带有评论标签的那个,你只需要阅读它的InnerText
属性。
有关更多信息,请参阅 MSDN https://msdn.microsoft.com/en-us/library/system.xml.xmlelement.innertext%28v=vs.110%29.aspx。
【讨论】:
以上是关于如何从 xmlnodelist 获取 xml 节点的主要内容,如果未能解决你的问题,请参考以下文章
C#将多个XMLNode或XMLNodeList从一个XMLDocument复制到另一个XMLDocument