我如何从 xml 节点列表中获取 xml 节点

How do i get xml nodes from the xmlnodelist

我想获取我的 table 调用数据中的子节点列表。我已经设法获得值节点并循环抛出每个节点。现在我想对我的评论标签中的节点做同样的事情。我不知道如何在评论标签(字体、数据戳和评论)中获取节点。

<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"))
                   {
                   }
                }
            }

您的 <comment>...</comment> 以一种特殊的 XmlNode 类型结束,称为 XmlElement。所以一旦你得到正确的XmlElement,有注释标签的那个,你只需要阅读它的InnerText 属性.

有关更多信息,请参阅 MSDN https://msdn.microsoft.com/en-us/library/system.xml.xmlelement.innertext%28v=vs.110%29.aspx

如果这是你的 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]");

要完成这项工作,您可以像这样形成一个聚合:

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

}   

并将其与数据网格视图绑定使用:

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
    }
}