簡體   English   中英

如何從 XmlReader 讀取而不向前移動?

[英]How to read from an XmlReader without moving it forwards?

我得到了這個場景:

while (reader.Read())
{
    if (reader.NodeType == XmlNodeType.Element && reader.Name == itemElementName)
    {
        XElement item = null;
        try
        {
            item = XElement.ReadFrom(reader) as XElement;
        }
        catch (XmlException ex)
        {
           //log line number and stuff from XmlException class  
        }
    }
}

在上面的循環中,我將某個節點 (itemElementName) 轉換為 XElement。

某些節點將是良好的 XML,並且會進入 XElement,但是,有些則不會。

在 CATCH 中,我不僅想捕獲標准的 XmlException 內容……我還想捕獲當前 Xml 和字符串的提取物。

但是,如果我在將節點傳遞給 XElement 之前在節點上執行任何類型的 READ 操作,它會將讀取器向前移動。

如何在不干擾閱讀器位置的情況下獲取閱讀器 OuterXml 內容的“快照”?

實際上 ReadSubtree 將返回一個“包裝”原始閱讀器的閱讀器。 因此,通讀新書最終也會推進原書。 您必須將 XmlReader 視為僅向前閱讀器,它根本無法返回。 至於您的場景,您可以詢問讀者在輸入文件中的位置,而不是試圖記住部分 XML。 只需將其轉換為 IXmlLineInfo 接口,它就有返回行和位置的方法。 使用它,您可以記住一些起始位置(在相關元素之前),然后是錯誤的結束位置。 然后從輸入文件中以純文本形式讀取該部分。

另一個想法:讀取外部 XML(使閱讀器前進),然后從這個 XML 創建一個新的閱讀器,它允許您“返回”並處理當前節點的元素。

while (r.ReadToFollowing("ParentNode"))
{
    parentXml = r.ReadOuterXml();

    //since ReadOuterXml() advances the reader to the next parent node, create a new reader to read the remaining elements of the current parent
    XmlReader r2 = XmlReader.Create(new StringReader(parentXml));
    r2.ReadToFollowing("ChildNode");
    childValue = r2.ReadElementContentAsString();
    r2.Close();
}                  

不要在閱讀器上使用任何“讀取”操作 - 正如您所發現的,這會推進它。 使用對reader.HasValuereader.Value等屬性的調用來檢查內容。 在對象瀏覽器中查找“XmlReader”,您可以讀取很多屬性。

編輯:我認為沒有一種簡單的方法可以簡單地獲取 XML,可能是因為當前節點本身可能不是有效的 XML,例如 XmlWhiteSpace、XmlText 節點甚至 XmlAttribute。

我所做的只是將元素讀入 XmlDocument,然后讀取它。 就我而言,我必須將流文檔轉換為 HTML。 我必須讀取一個內部元素來為父 HTML 元素分配一個“樣式”。

事實上,盡管 Vitek Karas MSFT 是對的,但 Helena Kupkova 在https://msdn.microsoft.com/en-us/library/aa302292.aspx上發布了一個靈巧的小型 XML 書簽閱讀器。 這允許使用緩存向后退。

與 ReadSubtree 類似的東西

using (XmlReader reader = XmlReader.Create(new StringReader(xml)))
                                {
                                    reader.MoveToContent();
                                    while (reader.Read())
                                    {
                                        switch (reader.NodeType)
                                        {
                                            case XmlNodeType.Element:
                                                if (reader.Name == "Field") // for example i need to read node field
                                                {

                                                    XmlReader inner = reader.ReadSubtree();  // the reader stays in the same  position
                                                    XElement El = XElement.Load(inner) as XElement;
                                                    inner.Close();
                                                }
                                        }
                                    }
                                }

暫無
暫無

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

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