簡體   English   中英

如何在C#中讀寫XML文件而不依賴標簽名稱?

[英]how to read & write xml file in C# not rely on the tag name?

非常感謝您閱讀我的問題。

底部是我的xml文件的示例。請參考。

我之前做了一些xml文件,但是通過“ CMarkXml”。 “ IntoElement,OutofElement”非常清楚。

但是當C#...我迷路了..

1:如何在不使用標簽名稱的情況下讀寫我的xml文件。 我看到了一些有關C#對xml文件進行操作的文章,但所有文章都假定知道標簽名稱。

2:如果沒有標簽名稱,則很難或不推薦。 那么如何通過XmlDocument讀寫我的xml文件? (對不起,請不用玲,我對此感到非常暈眩...)。

3:我的想法是,對於xml文件,刪除一些部分,我們仍然可以通過xmldocument來解析該部分。

4:對於寫/修改xml文件,當然應該包含刪除一些部分,刪除一些“葉子”,更改屬性...

非常感謝您閱讀長期的問題,我將不勝感激。 如果您有一個好的示例代碼,但沒有大洲將其粘貼到此處,可以將其發送到“ erlvde@gmail.com”嗎?

<root>
    <a>i belong to a</a>
    <b>
        <bb>
            <bb>1</bb>
            <bb>2</bb>
            <bb>3</bb>
            <bb>4</bb>
            <bb>5</bb>
        </bb>
        <bb>
            <bb>1</bb>
            <bb>2</bb>
            <bb>3</bb>
            <bb>4</bb>
            <bb>5</bb>
        <bb>
    ....(other <bb>)
    </b>
</root>

將您的xml讀入XmlDocument

var xmlDocument = new XmlDocument();
xmlDocument.LoadXml("XML HERE");

訪問子節點:

xmlDocument.ChildNodes[1]

但是也很容易出錯

您還可以檢查是否有子節點:

xmlDocument.HasChildNodes

並獲得子節點數:

xmlDocument.ChildNodes.Count

在我看來,您的元素名稱包含標識符。 如果是這種情況,並且您可以控制XML模式,則強烈建議您更改XML以使其包含表示標識符的元素和/或屬性,然后使用內置的XmlSerializer類來與XML進行串行化。 它具有許多可用的修飾符,例如XmlElementXmlAttribute ,可用於格式化輸出。

是一個入門指南。

如果可能的話,將您的XML更改為如下所示,這將使操作變得更加簡單...同樣,如果有可能更改架構,則也是如此。

<root>
    <a>i belong to a</a>
    <b>
        <bb id="1">
            <bb>1</bb>
            <bb>2</bb>
            <bb>3</bb>
            <bb>4</bb>
            <bb>5</bb>
        </bb>
        <bb id="2">
            <bb>1</bb>
            <bb>2</bb>
            <bb>3</bb>
            <bb>4</bb>
            <bb>5</bb>
        <bb>
    </b>
</root>

編輯 此編輯內容將反映您對XML所做的更改


這是一個簡單的控制台應用程序,它將將對象序列化為XML文件,然后對其進行重新水化處理。

預期的XML

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <a>i belong to a</a>
  <b>
    <bb>
      <bb>1</bb>
      <bb>2</bb>
      <bb>3</bb>
      <bb>4</bb>
      <bb>5</bb>
    </bb>
    <bb>
      <bb>1</bb>
      <bb>2</bb>
      <bb>3</bb>
      <bb>4</bb>
      <bb>5</bb>
    </bb>
  </b>
</root>

簡單控制台應用程序演示

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            var items = new root
            {
                a = "i belong to a",
                b = new List<bb>
                {
                    new bb
                    {
                        bbClassProperty = new List<int>
                        {
                            1,
                            2,
                            3,
                            4,
                            5
                        }
                    },
                    new bb
                    {
                        bbClassProperty= new List<int>
                        {
                            1,
                            2,
                            3,
                            4,
                            5
                        }
                    }
                }
            };

            XmlSerializer serializer = new XmlSerializer(typeof(root));

            using (var textWriter = new StreamWriter(@"C:\root.xml"))
            {
                serializer.Serialize(textWriter, items);
                textWriter.Close();
            }

            using (var stream = new StreamReader(@"C:\root.xml"))
            {
                var yourObject = serializer.Deserialize(stream);
            }

            Console.Read();
        }
    }

    #region [Classes]

    public class root
    {
        public string a { get; set; }

        public List<bb> b { get; set; }
    }

    public class bb
    {
        [XmlElement("bb")]
        public List<int> bbClassProperty { get; set; }
    }

    #endregion
}

查看XmlElement對象上的ChildNodes (和類似的)屬性和方法。 這些將使您可以遍歷節點的子代,然后可以要求該節點提供其名稱。

如果您有XmlNode對象,則可以使用XMLNode.FirstChild獲取該子對象(如果有)。 您還可以使用XMLNode.NextSibling獲取同一父節點的下一個Node。 為什么不能使用節點名稱? 這是最簡單,最常見的方式。 特別是如果您使用XPath或類似的東西。

XPath也是第二個問題的答案。

U可以使用XML閱讀器類, 這里給出一個簡單的示例。

using System;
using System.Xml;

class Program
{
    static void Main()
    {
    // Create an XML reader for this file.
    using (XmlReader reader = XmlReader.Create("perls.xml"))
    {
        while (reader.Read())
        {
        // Only detect start elements.
        if (reader.IsStartElement())
        {
            // Get element name and switch on it.
            switch (reader.Name)
            {
            case "perls":
                // Detect this element.
                Console.WriteLine("Start <perls> element.");
                break;
            case "article":
                // Detect this article element.
                Console.WriteLine("Start <article> element.");
                // Search for the attribute name on this current node.
                string attribute = reader["name"];
                if (attribute != null)
                {
                Console.WriteLine("  Has attribute name: " + attribute);
                }
                // Next read will contain text.
                if (reader.Read())
                {
                Console.WriteLine("  Text node: " + reader.Value.Trim());
                }
                break;
            }
        }
        }
    }
    }
}

輸入文件的文本為:

<?xml version="1.0" encoding="utf-8" ?>
<perls>
    <article name="backgroundworker">
    Example text.
    </article>
    <article name="threadpool">
    More text.
    </article>
    <article></article>
    <article>Final text.</article>
</perls>

輸出量

起始元素。

起始元素。

具有屬性名稱:backgroundworker

文本節點:示例文本。

起始元素。

具有屬性名稱:threadpool

文本節點:更多文本。

起始元素。

文字節點:

起始元素。

文本節點:最終文本。 enter code here

在上面的示例中,如果文件不包含標題,則可以使用以下代碼。

XmlReaderSettings settings = new XmlReaderSettings();
                settings.ConformanceLevel = ConformanceLevel.Fragment;
reader = XmlReader.Create(filePath, settings)

這樣的幫助嗎?

void Iterate(XmlNode parent) {
    //do something with
    //parent.Name
    //parent.Value
    //parent.Attributes

    foreach(XmlNode child in parent.ChildNodes) {
        Iterate(child);
    }
}

XmlDocument document = new XmlDocument();
document.Load(filename);

XmlNode parent = document.DocumentElement;
Iterate(parent);

您也可以這樣存儲它(對不起任何語法錯誤,沒有運行它)

public class Document {
    public Element DocumentElement { set; get; }

    private void Load(string fileName) {
        XmlDocument document = new XmlDocument();
        document.Load(fileName);

        DocumentElement = new Element(this, null);
        DocumentElement.Load(document.DocumentElement);
    }
}

public class Element {
    public string Name { set; get; }
    public string Value { set; get; }
    //other attributes

    private Document document = null;
    private Element parent = null;
    public Element Parent { get { return parent; } }
    public List<Element> Children { set; get; }
    private int order = 0;

    public Element(Document document, Element parent) {
        Name = "";
        Value = "";
        Children = new List<LayoutElement>();

        this.document = document;
        this.parent = parent;
        order = parent != null ? parent.Children.Count + 1 : 1;
    }

    private Element GetSibling(bool left) {
        if(parent == null) return null;
        int add = left ? -1 : +1;
        Element sibling = parent.Children.Find(child => child.order == order + add);
        return sibling;
    }

    public Element GetLeftSibling() {
        return GetSibling(true);
    }

    public Element GetRightSibling() {
        return GetSibling(false);
    }

    public void Load(XmlNode node) {
        Name = node.Name;
        Value = node.Value;
        //other attributes

        foreach(XmlNode nodeChild in node.Children) {
            Element child = new Element(document, this);
            child.Load(nodeChild);
            Children.Add(child);
        }
    }
}

Document document = new Document();
document.Load(fileName);

為了立即更改/刪除,您可以遍歷樹並按名稱查找元素,但是由於名稱不是唯一的,因此您會同時影響許多元素。 您可以在每個標簽中添加唯一的ID,例如

<bb id="bb1"/>

然后像讀取功能一樣讀取它

id = ((XmlElement)node).GetAttribute("id");

並使用此ID遍歷樹。 抱歉,我現在沒有時間提供更詳細的信息。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM