1

XML の新機能。要素の値を更新して戻す必要がある XML ドキュメントを提供するサード パーティの Web サービスがあります。核となる問題は、以下のコードで node.RemoveAll() メソッドを呼び出すときに NullReferenceException エラーが発生することです。各要素には、提供されたときに xsi:nil 属性があるため、RemoveAll() メソッドを呼び出しています。要素の値を更新する前にそれを削除しないと、XML は Web サービスによって検証されません。

サード パーティの Web サービスによって提供される XML ドキュメントは次のとおりです。

<?xml version="1.0" encoding="utf-16"?>
<TaskData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schema.sample.com/application/1/520800B">
  <Global>
    <RequestInfo xmlns="http://schema.sample.com/application/1/Types">
      <Requestor xsi:nil="true" />
      <Date_init xsi:nil="true" />
      <Shipto xsi:nil="true" />
      <Customer xsi:nil="true" />
      <Contact xsi:nil="true" />
      <Requestor_Email xsi:nil="true" />      
    </RequestInfo>    
   </Global>
  </TaskData>

私が見た他のソリューションでは XmlNamespaceManager を使用していましたが、機能させることができませんでした。この xml ドキュメントには、TaskData 要素に指定された名前空間と、RequestInfo 要素に別の名前空間が指定されています。名前空間ごとに XmlNamespaceManager 変数を指定しようとしましたが、同じ結果が得られました..ブレーク モードで nsmgr 変数にカーソルを合わせると、「子を評価できませんでした」と DefaultNamespace プロパティが空の文字列であることがわかります。

Public Sub testxml()

    Dim doc As New XmlDocument
    doc.Load("c:\temp\sample.xml")

    Dim nsmgr As XmlNamespaceManager = New XmlNamespaceManager(doc.NameTable)
    nsmgr.AddNamespace("s", "http://schema.sample.com/application/1/520800B")

    Dim node As XmlNode = doc.SelectSingleNode("s:Requestor", nsmgr)
    node.RemoveAll()
    node.InnerText = "Your Name Goes Here"

    doc.Save("c:\temp\sample.xml")

End Sub
4

4 に答える 4

2

問題は次のステートメントにあります。

doc.SelectSingleNode("s:Requestor", nsmgr)

あなたがする必要があるのは

doc.SelectSingleNode("//s:Requestor",nsmgr)

「s:Requestor」は、現在のノード名 s:Requestor の下にあるノードを教えてくれることを意味します

「//s:Requestor」は、s:Requestor という名前のドキュメント内のすべてのノードを提供することを意味します

あなたができる名前空間を無視したい場合

doc.SelectSingleNode("//*[local-name()='Requestor']")
于 2009-06-09T21:39:28.530 に答える
1

コードに 2 つのエラーがあります。1 つは、ノードの選択に使用される XPath です (Greg が指摘したように)。2 つ目は名前空間です。私が間違っているかもしれませんが、XML ドキュメントを解釈すると、TaskData要素には次の名前空間宣言があります。

xmlns="http://schema.sample.com/application/1/520800B"

...接頭辞なしで要素の名前空間を設定します。

しかし、RequestInfoタグには次の名前空間宣言があります。

xmlns="http://schema.sample.com/application/1/Types"

したがって、RequestInfoタグ内には、プレフィックスのないタグ用の別の名前空間があります。コードでは、これら 2 つの名前空間の最初の名前空間を使用して、2 番目の名前空間に存在するタグを一致させますが、これはうまくいきません。それを解決するには2つの方法があります。1 つは、コード内の名前空間を単純に変更することです。

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("s", "http://schema.sample.com/application/1/Types");
XmlNode node = doc.SelectSingleNode("//s:Requestor", nsmgr);

2 つ目は、両方の名前空間を定義し、タグへのフル パスを示す XPath 式を使用することです。

XmlNamespaceManager nsmgr = new XmlNamespaceManager(doc.NameTable);
nsmgr.AddNamespace("r", "http://schema.sample.com/application/1/520800B");
nsmgr.AddNamespace("s", "http://schema.sample.com/application/1/Types");
XmlNode node = doc.SelectSingleNode(@"/r:TaskData/r:Global/s:RequestInfo/s:Requestor", nsmgr);

どちらの場合も同じ結果になります。nodeありませんnull

于 2009-06-09T22:05:50.397 に答える
0

あなたの仕事を正しく理解しているかどうかわかりません。しかし、 xsi:nil="true" の部分だけを削除する必要がある場合は、それを文字列として読み込んで、

string.replace("xsi:nil=\"true\"", "")

もちろん、これは最もクリーンな解決策ではありませんが、私はまだ C# の XML 処理 API に慣れていないので、慣れるために MSDN を参照する必要があります。多分これはあなたの問題を解決します。

于 2009-06-09T21:29:42.250 に答える