XPathNavigator クラスは、XML ドキュメント内のノードと値を変更するために使用される一連のメソッドを提供します。 これらのメソッドを使用するには、 XPathNavigator オブジェクトを編集可能にする必要があります。つまり、 CanEdit プロパティを true
する必要があります。
XPathNavigatorXML ドキュメントを編集できるオブジェクトは、CreateNavigator クラスのXmlDocument メソッドによって作成されます。 XPathNavigator XPathDocument クラスによって作成されたオブジェクトは読み取り専用であり、XPathNavigator オブジェクトによって作成されたXPathDocument オブジェクトの編集メソッドを使用しようとすると、NotSupportedExceptionが発生します。
編集可能な XPathNavigator オブジェクトの作成の詳細については、「 XPathDocument と XmlDocument を使用した XML データの読み取り」を参照してください。
ノードの変更
ノードの値を変更する簡単な手法は、SetValue クラスのSetTypedValueメソッドとXPathNavigator メソッドを使用することです。
次の表に、これらのメソッドがさまざまなノード タイプに及ぼす影響を示します。
XPathNodeType | 変更されたデータ |
---|---|
Root | サポートされていません。 |
Element | 要素の内容。 |
Attribute | 属性の値。 |
Text | テキスト コンテンツ。 |
ProcessingInstruction | ターゲットを除くコンテンツ。 |
Comment | コメントの内容。 |
Namespace | サポートされていない。 |
XPathNavigator クラスには、ノードの挿入と削除に使用する一連のメソッドも用意されています。 XML ドキュメントのノードの挿入と削除の詳細については、「 XPathNavigator を使用した XML データの挿入」および「XPathNavigator を 使用した XML データの削除 」トピックを参照してください。
型指定されていない値の変更
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 メソッドによって挿入された新しい値は、値が設定される前に単純型のファセットに対してチェックされます。 ノードの型に従って新しい値が無効な場合 (たとえば、型が-1
の要素にxs:positiveInteger
の値を設定するなど)、例外が発生します。
次の例では、price
ファイル内の最初のbook
要素のcontosoBooks.xml
要素の値をDateTime値に変更しようとしています。
price
要素の XML スキーマ型は、xs:decimal
ファイル内で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>
厳密に型指定された XML データの編集の効果
XPathNavigator クラスは、厳密に型指定された XML を記述するための基礎として W3C XML スキーマを使用します。 要素と属性には、W3C XML スキーマ ドキュメントに対する検証に基づいて型情報で注釈を付けることができます。 他の要素または属性を含めることができる要素は複合型と呼ばれ、テキスト コンテンツのみを含めることができる要素は単純型と呼ばれます。
注
属性には単純型のみを使用できます。
要素または属性は、型定義に固有のすべての規則に準拠している場合、スキーマ有効と見なすことができます。 単純型 xs:int
を持つ要素には、スキーマが有効 -2147483648 と2147483647の間に数値を含める必要があります。 複合型の場合、要素のスキーマの有効性は、その子要素と属性のスキーマの有効性に依存します。 したがって、要素が複合型定義に対して有効な場合、そのすべての子要素と属性は、その型定義に対して有効です。 同様に、要素のいずれかの子要素または要素の属性が型定義に対して無効であるか、または不明な有効性を持っている場合、要素も無効であるか、または不明な有効性になります。
要素の有効性が子要素と属性の有効性に依存していることを考えると、いずれかの要素を変更すると、以前に有効であった場合に要素の有効性が変更されます。 具体的には、要素の子要素または属性が挿入、更新、または削除された場合、要素の有効性は不明になります。 これは、Validityに設定されている要素のSchemaInfo プロパティのNotKnown プロパティによって表されます。 さらに、要素の親要素 (およびその親要素など) の有効性も不明になるため、この効果は XML ドキュメント全体で再帰的にカスケードされます。
スキーマ検証と XPathNavigator クラスの詳細については、「 XPathNavigator を使用したスキーマ検証」を参照してください。
属性の変更
SetValueメソッドとSetTypedValueメソッドを使用して、型指定されていない属性ノードと型指定された属性ノード、および「ノードの変更」セクションに記載されているその他のノード の種類を変更できます。
次の例では、genre
ファイル内の最初のbook
要素のbooks.xml
属性の値を変更します。
Dim document As XmlDocument = New XmlDocument()
document.Load("books.xml")
Dim navigator As XPathNavigator = document.CreateNavigator()
navigator.MoveToChild("bookstore", String.Empty)
navigator.MoveToChild("book", String.Empty)
navigator.MoveToAttribute("genre", String.Empty)
navigator.SetValue("non-fiction")
navigator.MoveToRoot()
Console.WriteLine(navigator.OuterXml)
XmlDocument document = new XmlDocument();
document.Load("books.xml");
XPathNavigator navigator = document.CreateNavigator();
navigator.MoveToChild("bookstore", String.Empty);
navigator.MoveToChild("book", String.Empty);
navigator.MoveToAttribute("genre", String.Empty);
navigator.SetValue("non-fiction");
navigator.MoveToRoot();
Console.WriteLine(navigator.OuterXml);
SetValueメソッドとSetTypedValueメソッドの詳細については、「型指定されていない値の変更」および「型指定された値の変更」セクションを参照してください。
InnerXml プロパティと OuterXml プロパティ
InnerXml クラスのOuterXmlプロパティとXPathNavigatorプロパティは、XPathNavigator オブジェクトが現在配置されているノードの XML マークアップを変更します。
InnerXml プロパティは、XPathNavigator オブジェクトが現在配置されている子ノードの XML マークアップを、指定された XML string
の解析された内容と共に変更します。 同様に、 OuterXml プロパティは、 XPathNavigator オブジェクトが現在配置されている子ノードと現在のノード自体の XML マークアップを変更します。
次の例では、OuterXml プロパティを使用してprice
要素の値を変更し、discount
ファイルの最初のbook
要素に新しいcontosoBooks.xml
属性を挿入します。
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.OuterXml = "<price discount=\"0\">10.99</price>"
navigator.MoveToRoot()
Console.WriteLine(navigator.OuterXml)
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.OuterXml = "<price discount=\"0\">10.99</price>";
navigator.MoveToRoot();
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>
名前空間ノードの変更
ドキュメント オブジェクト モデル (DOM) では、名前空間宣言は、挿入、更新、および削除できる通常の属性であるかのように扱われます。 次の例に示すように、名前空間ノードの値を変更すると、名前空間ノードのスコープ内の要素と属性の ID が変更される可能性があるため、 XPathNavigator クラスは名前空間ノードに対してこのような操作を許可しません。
<root xmlns="http://www.contoso.com">
<child />
</root>
上記の XML の例を次のように変更すると、各要素の名前空間 URI の値が変更されるため、ドキュメント内のすべての要素の名前が実質的に変更されます。
<root xmlns="urn:contoso.com">
<child />
</root>
名前空間宣言と競合しない名前空間ノードを挿入対象のスコープに挿入することは、 XPathNavigator クラスで許可されます。 この場合、名前空間宣言は XML ドキュメントの下位スコープでは宣言されず、次の例に示すように名前が変更されることはありません。
<root xmlns:a="http://www.contoso.com">
<parent>
<a:child />
</parent>
</root>
上記の XML の例が次のように変更された場合、名前空間宣言は、他の名前空間宣言のスコープの下にある XML ドキュメント全体に正しく反映されます。
<root xmlns:a="http://www.contoso.com">
<parent a:parent-id="1234" xmlns:a="http://www.contoso.com/parent-id">
<a:child xmlns:a="http://www.contoso.com/" />
</parent>
</root>
上記の XML の例では、a:parent-id
名前空間のparent
要素に属性http://www.contoso.com/parent-id
が挿入されています。
CreateAttribute メソッドは、parent
要素に配置されている間に属性を挿入するために使用されます。
http://www.contoso.com
名前空間宣言は、XML ドキュメントの残りの部分の一貫性を維持するために、XPathNavigator クラスによって自動的に挿入されます。
エンティティ参照ノードの変更
XmlDocument オブジェクト内のエンティティ参照ノードは読み取り専用であり、XPathNavigatorクラスまたはXmlNode クラスを使用して編集することはできません。 エンティティ参照ノードを変更しようとすると、 InvalidOperationExceptionが発生します。
xsi:nil ノードの変更
W3C XML スキーマの推奨事項では、要素が nillable であるという概念が導入されています。 要素が nillable の場合、要素にコンテンツがなく、有効なままである可能性があります。 要素の概念は、 null
されるオブジェクトの概念に似ています。 主な違いは、 null
オブジェクトに何らかの方法でアクセスできないのに対し、 xsi:nil
要素には、アクセスできるがコンテンツ (子要素やテキスト) を持たない属性などのプロパティが残っている点です。 XML ドキュメント内の要素にxsi:nil
値を持つtrue
属性の存在は、要素にコンテンツがないことを示すために使用されます。
XPathNavigator オブジェクトを使用して、xsi:nil
の値を持つtrue
属性を持つ有効な要素にコンテンツを追加する場合、そのxsi:nil
属性の値はfalse
に設定されます。
注
xsi:nil
属性が false
に設定されている要素の内容が削除された場合、属性の値は true
に変更されません。
XML ドキュメントの保存
このトピックで説明する編集メソッドの結果として XmlDocument オブジェクトに加えられた変更の保存は、 XmlDocument クラスのメソッドを使用して実行されます。 XmlDocument オブジェクトに加えられた変更の保存の詳細については、「ドキュメントの保存と書き込み」を参照してください。
こちらも参照ください
.NET