6

ItemID の入力を受け入れ、対応するアイテム番号を返す、Oracle によって公開された WebService を呼び出しています。応答に含まれる XML から返されたアイテム番号を取得したいと考えています。

XML は次のようになります。

<env:Envelope
  xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:ns0="http://dev1/MyWebService1.wsdl">
 <env:Header>
  <wsse:Security
    xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
    xmlns:env="http://schemas.xmlsoap.org/soap/envelope/"
    env:mustUnderstand="1"/>
 </env:Header>
 <env:Body>
  <ns0:getItemNbrByItemIdResponseElement>
   <ns0:result>1010603</ns0:result>
  </ns0:getItemNbrByItemIdResponseElement>
 </env:Body>
</env:Envelope>

<ns0:result>1010603</ns0:result>特に 1010603 のみを取得することに興味があります。

私は C# を使用して XML を解析する作業をあまり行っていません。これまでのところ、いくつかの異なる方法で遊んでいます。これを行うための推奨される方法は何ですか?

私はVS2008を使用しています(XPathが利用可能など)

4

6 に答える 6

15

個人的には LINQ to XML を使用します。特に名前空間が関係している場合は、XPath よりも処理が簡単だからです。次のようにします。

XNamespace ns0 = "http://dev1/MyWebService1.wsdl";

String result = doc.Descendants(ns0 + "result").First().Value;

here はではなくであるdocことが期待されることに注意してください。(私の推測では、これがあなたに表示されなかった理由です。)XDocumentXmlDocument

于 2008-12-17T14:46:49.570 に答える
5

fwiw次のようなxp​​athを使用して名前空間の問題をごまかすことができます。//*[local-name()='result']

于 2008-12-17T14:54:09.010 に答える
3

Linq を使用したくない場合は、XPathDocument を使用して値を取得できます。

XPathDocument xmldoc = new XPathDocument(@"C:\tmp\sample.xml");
XPathNavigator nav = xmldoc.CreateNavigator();

XmlNamespaceManager nsMgr = new XmlNamespaceManager(nav.NameTable);
nsMgr.AddNamespace("ns0", "http://dev1/MyWebService1.wsdl");

XPathNavigator result = nav.SelectSingleNode("//ns0:result", nsMgr);
System.Diagnostics.Debug.WriteLine(result.Value);

XPathDocument はメモリ使用量が少なく、シナリオでは XmlDocument よりも高速である可能性が高くなります。XmlDocument はメモリ内に XML ドキュメントの完全なオブジェクト モデルを構築しますが、XPathDocument はそれを行いません。

于 2008-12-17T14:52:40.960 に答える
2

私の頭の上から、次のように動作するはずです:

XmlDocument doc = new XmlDocument();
doc.PreserveWhitespace = true;

XmlNamespaceManager mgr = GetNamespace(doc);
doc.LoadXml(xmltext);

XmlNode nd = doc.DocumentElement.SelectSingleNode("//ns0:result", mgr);

名前空間のコードは次のようになります。

private XmlNamespaceManager GetNamespace(XmlDocument document)
{
    XmlNamespaceManager mgr = new XmlNamespaceManager(document.NameTable);
    mgr.AddNamespace("ns0", "http://dev1/MyWebService1.wsdl");
    return mgr;
}

XML ドキュメントには名前空間が関連付けられており、XPath はこれをクエリ解決に使用するため、名前空間マネージャーを使用する必要があります。

于 2008-12-17T14:51:55.707 に答える
1

これを解決するために、Jon Skeet の回答を使用しました。これを機能させるために実装しなければならなかったコードは次のとおりです(他の人の将来の利益のために)。

XmlDocument xmlDoc = new XmlDocument();

XNamespace ns0 = "http://dev1/MyWebService1.wsdl";

xmlDoc.Load(request.GetResponse().GetResponseStream());

XDocument xDoc = XDocument.Load(new XmlNodeReader(xmlDoc));                          

String result = xDoc.Descendants(ns0 + "result").First().Value;

もちろん、これはrequestという名前の HttpWebRequest から応答を取得していることを前提としています。

于 2008-12-17T16:42:24.330 に答える
0

この質問には非常に良い完全な答えがあります。

好奇心から、この特定のケースでは非常に単純なXPath式が機能することを付け加えておきます。

    normalize-space(/)

これは、以下の2行のようなものを使用してC#で簡単に実行できます。

        XPathNavigator navigator = document.CreateNavigator();

        string res = (string)navigator.Evaluate("normalize-space(/)");

.NET XPathエンジンを適切に最適化すると、その評価も効率的になる可能性があります。

于 2008-12-17T15:30:38.653 に答える