類別 XPathNavigator 提供一組方法,用來在 XML 檔中插入同層級、子節點和屬性節點。 若要使用這些方法, XPathNavigator 對象必須可編輯,也就是說,其 CanEdit 屬性必須是 true。
XPathNavigator 可以編輯 XML 檔的物件是由 CreateNavigator 類別的 XmlDocument 方法所建立。 XPathNavigator類別所XPathDocument建立的物件是唯讀的,而且任何嘗試使用 物件所XPathNavigator建立之對象的編輯方法XPathDocument會導致 NotSupportedException。
如需建立可 XPathNavigator 編輯對象的詳細資訊,請參閱 使用 XPathDocument 和 XmlDocument 讀取 XML 數據。
插入節點
類別 XPathNavigator 提供在 XML 檔中插入同層級、子節點和屬性節點的方法。 這些方法可讓您在與物件目前位置 XPathNavigator 相關的不同位置插入節點和屬性,如下列各節所述。
插入同層級節點
類別 XPathNavigator 提供下列方法來插入同層級節點。
這些方法會在物件目前所在的節點前後插入同層級節點 XPathNavigator 。
InsertAfter和 InsertBefore 方法會多載並接受 string、XmlReader物件或XPathNavigator物件,其中包含要新增為參數的同層級節點。 這兩種方法 XmlWriter 也會傳回用來插入同層級節點的物件。
InsertElementAfter和 InsertElementBefore 方法會在 節點前後插入單一同層級節點XPathNavigator,物件目前使用命名空間前置詞、本機名稱、命名空間 URI 和指定為參數的值來定位物件。
在下列範例中,會在檔案中第一pages個專案的子專案之前price插入新的book元素contosoBooks.xml。
XmlDocument document = new XmlDocument();
document.Load("contosoBooks.xml");
XPathNavigator navigator = document.CreateNavigator();
navigator.MoveToChild("bookstore", "http://www.contoso.com/books");
navigator.MoveToChild("book", "http://www.contoso.com/books");
navigator.MoveToChild("price", "http://www.contoso.com/books");
navigator.InsertBefore("<pages>100</pages>");
navigator.MoveToParent();
Console.WriteLine(navigator.OuterXml);
Dim document As XmlDocument = New XmlDocument()
document.Load("contosoBooks.xml")
Dim navigator As XPathNavigator = document.CreateNavigator()
navigator.MoveToChild("bookstore", "http://www.contoso.com/books")
navigator.MoveToChild("book", "http://www.contoso.com/books")
navigator.MoveToChild("price", "http://www.contoso.com/books")
navigator.InsertBefore("<pages>100</pages>")
navigator.MoveToParent()
Console.WriteLine(navigator.OuterXml)
此範例會將 contosoBooks.xml 檔案當作輸入。
<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
如需、 InsertAfterInsertBefore和 InsertElementAfter 方法的詳細資訊InsertElementBefore,請參閱XPathNavigator類別參考檔。
插入子節點
類別 XPathNavigator 提供下列方法來插入子節點。
這些方法會將子節點附加至 結尾,以及物件目前所在的節點 XPathNavigator 子節點清單開頭。
如同[插入同層級節點] 區段中的方法, AppendChild 和 PrependChild 方法會接受 string包含子節點以新增為參數的、 XmlReader 物件或 XPathNavigator 物件。 這兩種方法 XmlWriter 也會傳回用來插入子節點的物件。
此外,如同「插入同層級節點」區段中的方法, AppendChildElement 和 PrependChildElement 方法會將單一子節點插入至 結尾,以及物件目前使用命名空間前置詞、本機名稱、命名空間 URI 和指定為參數之節點 XPathNavigator 子節點清單的開頭。
在下列範例中,會將新的pages子專案附加至檔案中book第一contosoBooks.xml個專案的子項目清單。
XmlDocument document = new XmlDocument();
document.Load("contosoBooks.xml");
XPathNavigator navigator = document.CreateNavigator();
navigator.MoveToChild("bookstore", "http://www.contoso.com/books");
navigator.MoveToChild("book", "http://www.contoso.com/books");
navigator.AppendChild("<pages>100</pages>");
Console.WriteLine(navigator.OuterXml);
Dim document As XmlDocument = New XmlDocument()
document.Load("contosoBooks.xml")
Dim navigator As XPathNavigator = document.CreateNavigator()
navigator.MoveToChild("bookstore", "http://www.contoso.com/books")
navigator.MoveToChild("book", "http://www.contoso.com/books")
navigator.AppendChild("<pages>100</pages>")
Console.WriteLine(navigator.OuterXml)
此範例會將 contosoBooks.xml 檔案當作輸入。
<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
如需、 AppendChildPrependChild和 AppendChildElement 方法的詳細資訊PrependChildElement,請參閱XPathNavigator類別參考檔。
插入屬性節點
類別 XPathNavigator 提供下列方法來插入屬性節點。
這些方法會在物件目前所在的項目節點上插入屬性節點 XPathNavigator 。 方法 CreateAttribute 會在物件目前所在的項目節點上建立屬性節點 XPathNavigator ,並使用命名空間前置詞、區域名稱、命名空間 URI 和指定為參數的值。 方法會CreateAttributesXmlWriter傳回用來插入屬性節點的物件。
在下列範例中,會使用 discount 從 currency 方法傳回的物件,在檔案中price第一個專案book的子專案上contosoBooks.xml建立新的 XmlWriter 和 CreateAttributes 屬性。
XmlDocument document = new XmlDocument();
document.Load("contosoBooks.xml");
XPathNavigator navigator = document.CreateNavigator();
navigator.MoveToChild("bookstore", "http://www.contoso.com/books");
navigator.MoveToChild("book", "http://www.contoso.com/books");
navigator.MoveToChild("price", "http://www.contoso.com/books");
XmlWriter attributes = navigator.CreateAttributes();
attributes.WriteAttributeString("discount", "1.00");
attributes.WriteAttributeString("currency", "USD");
attributes.Close();
navigator.MoveToParent();
Console.WriteLine(navigator.OuterXml);
Dim document As XmlDocument = New XmlDocument()
document.Load("contosoBooks.xml")
Dim navigator As XPathNavigator = document.CreateNavigator()
navigator.MoveToChild("bookstore", "http://www.contoso.com/books")
navigator.MoveToChild("book", "http://www.contoso.com/books")
navigator.MoveToChild("price", "http://www.contoso.com/books")
Dim attributes As XmlWriter = navigator.CreateAttributes()
attributes.WriteAttributeString("discount", "1.00")
attributes.WriteAttributeString("currency", "USD")
attributes.Close()
navigator.MoveToParent()
Console.WriteLine(navigator.OuterXml)
此範例會將 contosoBooks.xml 檔案當作輸入。
<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
如需 和 CreateAttribute 方法的詳細資訊CreateAttributes,請參閱XPathNavigator類別參考檔。
複製節點
在某些情況下,您可能會想要使用另一個 XML 檔案的內容填入 XML 檔。 類別XPathNavigator和 XmlWriter 類別都可以從現有的XmlDocument物件或XmlReader物件將節點XPathNavigator複製到物件。
類別AppendChild的 PrependChild 、 InsertBeforeInsertAfter和 XPathNavigator 方法都有可接受XPathNavigator物件或 XmlReader 物件做為參數的多載。
類別 WriteNode 的 XmlWriter 方法具有可接受 XmlNode、 XmlReader或 XPathNavigator 物件的多載。
下列範例會將所有 book 元素從一個檔複製到另一個檔。
Dim document As XmlDocument = New XmlDocument()
document.Load("books.xml")
Dim navigator As XPathNavigator = document.CreateNavigator()
navigator.MoveToChild("bookstore", String.Empty)
Dim newBooks As XPathDocument = New XPathDocument("newBooks.xml")
Dim newBooksNavigator As XPathNavigator = newBooks.CreateNavigator()
Dim nav As XPathNavigator
For Each nav in newBooksNavigator.SelectDescendants("book", "", false)
navigator.AppendChild(nav)
Next
document.Save("newBooks.xml");
XmlDocument document = new XmlDocument();
document.Load("books.xml");
XPathNavigator navigator = document.CreateNavigator();
navigator.MoveToChild("bookstore", String.Empty);
XPathDocument newBooks = new XPathDocument("newBooks.xml");
XPathNavigator newBooksNavigator = newBooks.CreateNavigator();
foreach (XPathNavigator nav in newBooksNavigator.SelectDescendants("book", "", false))
{
navigator.AppendChild(nav);
}
document.Save("newBooks.xml");
插入值
類別 XPathNavigator 會提供 SetValue 和 SetTypedValue 方法,將節點 XmlDocument 的值插入 物件中。
插入不具類型的值
方法 SetValue 僅將作為參數傳遞的不具型別的 string 值插入作為物件目前所在的節點上的 XPathNavigator 值。 如果架構資訊可用,值會在沒有任何類型或不驗證新值是否根據節點類型有效的情況下被插入。
在下列範例中,使用SetValue方法來更新price檔案中的所有contosoBooks.xml元素。
XmlDocument document = new XmlDocument();
document.Load("contosoBooks.xml");
XPathNavigator navigator = document.CreateNavigator();
XmlNamespaceManager manager = new XmlNamespaceManager(navigator.NameTable);
manager.AddNamespace("bk", "http://www.contoso.com/books");
foreach (XPathNavigator nav in navigator.Select("//bk:price", manager))
{
if (nav.Value == "11.99")
{
nav.SetValue("12.99");
}
}
Console.WriteLine(navigator.OuterXml);
Dim document As XmlDocument = New XmlDocument()
document.Load("contosoBooks.xml")
Dim navigator As XPathNavigator = document.CreateNavigator()
Dim manager As XmlNamespaceManager = New XmlNamespaceManager(navigator.NameTable)
manager.AddNamespace("bk", "http://www.contoso.com/books")
For Each nav As XPathNavigator In navigator.Select("//bk:price", manager)
If nav.Value = "11.99" Then
nav.SetValue("12.99")
End If
Next
Console.WriteLine(navigator.OuterXml)
此範例會將 contosoBooks.xml 檔案當作輸入。
<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
插入具類型的值
當節點的類型是W3C XML 架構簡單類型時,方法所插入 SetTypedValue 的新值會在設定值之前,針對簡單類型的 Facet 進行檢查。 如果新值根據節點的類型無效(例如,在類型為-1的項目上設定 值xs:positiveInteger),則會產生例外狀況。
下列範例會嘗試將檔案中第一個price元素的 book值變更為 contosoBooks.xml值。 由於 price 檔案中將 xs:decimal 元素的 XML 架構類型定義為 contosoBooks.xsd,因此會產生例外狀況。
Dim settings As XmlReaderSettings = New XmlReaderSettings()
settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd")
settings.ValidationType = ValidationType.Schema
Dim reader As XmlReader = XmlReader.Create("contosoBooks.xml", settings)
Dim document As XmlDocument = New XmlDocument()
document.Load(reader)
Dim navigator As XPathNavigator = document.CreateNavigator()
navigator.MoveToChild("bookstore", "http://www.contoso.com/books")
navigator.MoveToChild("book", "http://www.contoso.com/books")
navigator.MoveToChild("price", "http://www.contoso.com/books")
navigator.SetTypedValue(DateTime.Now)
XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");
settings.ValidationType = ValidationType.Schema;
XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);
XmlDocument document = new XmlDocument();
document.Load(reader);
XPathNavigator navigator = document.CreateNavigator();
navigator.MoveToChild("bookstore", "http://www.contoso.com/books");
navigator.MoveToChild("book", "http://www.contoso.com/books");
navigator.MoveToChild("price", "http://www.contoso.com/books");
navigator.SetTypedValue(DateTime.Now);
此範例會將 contosoBooks.xml 檔案當作輸入。
<?xml version="1.0" encoding="utf-8" ?>
<bookstore xmlns="http://www.contoso.com/books">
<book genre="autobiography" publicationdate="1981-03-22" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967-11-17" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991-02-15" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>
此範例也會採用 contosoBooks.xsd 做為輸入。
<?xml version="1.0" encoding="utf-8"?>
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" targetNamespace="http://www.contoso.com/books" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="bookstore">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="book">
<xs:complexType>
<xs:sequence>
<xs:element name="title" type="xs:string" />
<xs:element name="author">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="name" type="xs:string" />
<xs:element minOccurs="0" name="first-name" type="xs:string" />
<xs:element minOccurs="0" name="last-name" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="price" type="xs:decimal" />
</xs:sequence>
<xs:attribute name="genre" type="xs:string" use="required" />
<xs:attribute name="publicationdate" type="xs:date" use="required" />
<xs:attribute name="ISBN" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>
InnerXml 和 OuterXml 屬性
類別InnerXml的 OuterXml 和 XPathNavigator 屬性會變更物件目前所在的節點 XPathNavigator XML 標記。
InnerXml 屬性會根據指定的 XML XPathNavigator 剖析內容,變更物件 string 目前所在子節點的 XML 標記。 同樣地,OuterXml 屬性會更改目前物件所在的子節點和目前節點本身的 XML 標記。
除了本主題所述的方法之外, InnerXml 和 OuterXml 屬性也可以用來在 XML 檔中插入節點和值。 如需使用 和 屬性來插入節點和值的詳細資訊,請參閱InnerXml主題。OuterXml
命名空間和 xml:lang 衝突
使用xml:lang以 物件做為參數之 InsertBefore 類別InsertAfter的、 AppendChildPrependChild 和 XPathNavigator 方法插入 XML 數據時,可能會發生命名空間和XmlReader宣告範圍相關的某些衝突。
以下是可能的命名空間衝突。
如果對象內容中有 XmlReader 命名空間在範圍內,其中命名空間 URI 對應的前置詞不在對象的內容中 XPathNavigator ,則會將新的命名空間宣告新增至新插入的節點。
如果對象的內容和XmlReader對象內容內XPathNavigator有相同的命名空間 URI,但在兩個內容中都有對應到它的不同前置詞,則會將新的命名空間宣告新增至新插入的節點,並具有從 XmlReader 物件取得的前置詞和命名空間 URI。
如果相同的命名空間前置詞同時在對象的內容和XmlReader對象的內容範圍內XPathNavigator,但在這兩個內容中都有對應到它的不同命名空間 URI,則會將新的命名空間宣告新增至新插入的節點,以重新宣告從 XmlReader 物件取得之命名空間 URI 的前置詞。
如果對象內容和XmlReader對象內容中的XPathNavigator前置詞和命名空間 URI 相同,則不會將任何新的命名空間宣告新增至新插入的節點。
備註
上述描述也適用於命名空間宣告,其中包含空白 string 作為前置詞的命名空間宣告(例如,預設命名空間宣告)。
以下是可能的 xml:lang 衝突。
如果對象內容中有一個
xml:lang屬性在範圍內,但在對象的內容中XmlReader沒有屬性,XPathNavigator則會將值從xml:lang物件取得的屬性新增至新插入的XmlReader節點。如果對象的內容和
xml:lang物件內容中有XmlReader一個XPathNavigator屬性在範圍內,但每個屬性都有不同的值,xml:lang則會將值從 XmlReader 物件中取得的屬性加入至新插入的節點。如果對象的內容和
xml:lang對象內容中有XmlReader一個XPathNavigator屬性在範圍內,但每個屬性都有相同的值,則新插入的節點上不會新增任何新xml:lang屬性。如果對象內容中有
xml:lang某個XPathNavigator屬性在範圍內,但對象內容中XmlReader沒有任何現有屬性,則不會將任何xml:lang屬性新增至新插入的節點。
使用 XmlWriter 插入節點
用來插入同層級、子節點和屬性節點的方法會多載於「插入節點和值」一節中所述。 類別InsertAfter的 InsertBefore 、 AppendChildPrependChild和 CreateAttributesXPathNavigator 方法會傳回XmlWriter用來插入節點的物件。
不支援的 XmlWriter 方法
由於 XPath 資料模型與檔案物件模型 (DOM) 之間的差異,因此類別不支援XmlWriter使用 類別將資訊寫入 XML 檔XPathNavigator的所有方法。
下表描述 XmlWriter 類別不支援的 XPathNavigator 類別方法。
| 方法 | 說明 |
|---|---|
| WriteEntityRef | 擲回例外狀況 NotSupportedException 。 |
| WriteDocType | 在根層級忽略 ,並在 XML 檔中的任何其他層級呼叫 時擲回 NotSupportedException 例外狀況。 |
| WriteCData | 視為對等字元或字元之 WriteString 方法的呼叫。 |
| WriteCharEntity | 視為對等字元或字元之 WriteString 方法的呼叫。 |
| WriteSurrogateCharEntity | 視為對等字元或字元之 WriteString 方法的呼叫。 |
如需 類別 XmlWriter 的詳細資訊,請參閱 XmlWriter 類別參考檔。
多個 XmlWriter 物件
有多個物件指向具有 XPathNavigator 一或多個開啟 XmlWriter 物件之 XML 檔的不同部分。 在單個線程案例中允許和支援多個 XmlWriter 物件。
以下是使用多個 XmlWriter 物件時要考慮的重要注意事項。
呼叫每個XmlWriter物件的 方法時Close,物件XmlWriter所寫入的 XML 片段會新增至 XML 檔。 在那一點之前, XmlWriter 物件會寫入中斷聯機的片段。 如果在 XML 檔上執行作業,則呼叫 之前XmlWriter,物件Close所寫入的任何片段都不會受到影響。
如果特定 XML 子樹上有一個開啟 XmlWriter 的物件,而且該子樹遭到刪除,該 XmlWriter 物件仍可能會新增至子樹狀結構。 子樹只會變成已刪除的片段。
如果在 XML 檔中的同一點開啟多個 XmlWriter 物件,它們會以關閉物件的順序新增至 XML 檔,而不是以開啟物件的順序 XmlWriter 。
下列範例會 XmlDocument 建立 物件、建立 XPathNavigator 對象,然後使用 XmlWriter 方法傳 PrependChild 回的物件,在檔案中 books.xml 建立第一本書的結構。 然後,此範例會將它儲存為 book.xml 檔案。
Dim document As XmlDocument = New XmlDocument()
Dim navigator As XPathNavigator = document.CreateNavigator()
Using writer As XmlWriter = navigator.PrependChild()
writer.WriteStartElement("bookstore")
writer.WriteStartElement("book")
writer.WriteAttributeString("genre", "autobiography")
writer.WriteAttributeString("publicationdate", "1981-03-22")
writer.WriteAttributeString("ISBN", "1-861003-11-0")
writer.WriteElementString("title", "The Autobiography of Benjamin Franklin")
writer.WriteStartElement("author")
writer.WriteElementString("first-name", "Benjamin")
writer.WriteElementString("last-name", "Franklin")
writer.WriteElementString("price", "8.99")
writer.WriteEndElement()
writer.WriteEndElement()
writer.WriteEndElement()
End Using
document.Save("book.xml")
XmlDocument document = new XmlDocument();
XPathNavigator navigator = document.CreateNavigator();
using (XmlWriter writer = navigator.PrependChild())
{
writer.WriteStartElement("bookstore");
writer.WriteStartElement("book");
writer.WriteAttributeString("genre", "autobiography");
writer.WriteAttributeString("publicationdate", "1981-03-22");
writer.WriteAttributeString("ISBN", "1-861003-11-0");
writer.WriteElementString("title", "The Autobiography of Benjamin Franklin");
writer.WriteStartElement("author");
writer.WriteElementString("first-name", "Benjamin");
writer.WriteElementString("last-name", "Franklin");
writer.WriteElementString("price", "8.99");
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndElement();
}
document.Save("book.xml");
儲存 XML 檔
使用 類別的方法,儲存對 物件所做的 XmlDocument 變更,因為本主題所述的方法 XmlDocument 會執行。 如需儲存對物件所做的 XmlDocument 變更的詳細資訊,請參閱 儲存和寫入檔。