web-dev-qa-db-ja.com

このXMLを解析するにはどうすればよいですか(「ルート要素がありません」または「シーケンスに要素が含まれていません」を取得せずに)?

これはこの質問からの派生物です 「ルビコンを越えた」後にHttpWebRequest本体がnullになるのはなぜですか? 答えられました(1つのハードルが跳ね上がります)が、次のハードルが私をつまずかせます。

このコードで:

public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
    XDocument doc = XDocument.Parse(await Request.Content.ReadAsStringAsync()); 

...またはこれ:

XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());

...そしてこれを着信stringifiedXMLとして:

<?xml version=1.0?>
<LocateAndLaunch>
    <Tasks>Some Task</Tasks>
    <Locations>Some Location</Locations>
</LocateAndLaunch>

...例外が発生します: "System.Xml.XmlExceptionはユーザーコードによって処理されませんでしたHResult = -2146232000メッセージ=ルート要素がありません。"

このコード(同じstringifiedXML)の場合:

XDocument doc = XDocument.Parse(stringifiedXML);

...私は得る

System.InvalidOperationExceptionはユーザーコードによって処理されませんでしたHResult = -2146233079 Message = Sequenceには要素が含まれていませんSource = System.Core StackTrace:at System.Linq.Enumerable.First [TSource](IEnumerable`1 source)at HandheldServer.Controllers.DeliveryItemsController.d__2 .MoveNext()in c:\ HandheldServer\HandheldServer\Controllers\DeliveryItemsController.cs:line 109 InnerException:

IOW、着信文字列の解析方法に応じて、「ルート要素がありません」のいずれかが表示されます。または「シーケンスに要素が含まれていません

デュースマカリステアマクリーンバージニアウィーパーとは?!? <LocateAndLaunch>はルート要素ではありませんか? Some TaskおよびSome Location要素ではありませんか?

XDocumentなどを使用できずに、XMLを手動で分解する必要がありますか?

注:Fiddlerから、本文データ(XMLテキスト)の送信は機能します(送信したものは希望どおりに到着します)。しかし、それでも、サーバー上のXML解析コードは失敗します。

ただし、ハンドヘルド/ Compact Frameworkクライアントコードから同じデータを送信しようとすると、「=」を介してデータのみが送信されます(<xml version="のようなものがサーバーに渡されます。その後、クライアントに「」が表示されます。 リクエストが送信された後は、この操作を実行できません "

更新

したがって、Marcinの回答に基づくと、XDocument.Parse()に固執すれば大丈夫なはずであり、TToniの回答に基づくと、data/xml自体が不良である可能性があります。ファイルの内容は次のとおりです。

<?xml version="1.0"?>
<LocateAndLaunch>
    <Tasks>
    </Tasks>
    <Locations>
    </Locations>
</LocateAndLaunch>

したがって、バージョン番号の前後に引用符がありますが、どういうわけかこれらをエスケープする必要がありますか?これがデータが切り捨てられる理由です-最初の引用符(「1.0」の前)を見ると、それが文字列の終了であると見なされるためです。 ?

更新2

Marcin、着信「xml」データ(文字列)は、XDocumentコードに到達する前に切り捨てられます。

[Route("api/DeliveryItems/PostArgsAndXMLFileAsStr")]
public async void PostArgsAndXMLFileAsStr([FromBody] string stringifiedXML, string serialNum, string siteNum)
{
    string beginningInvoiceNum = string.Empty;
    string endingInvoiceNum = string.Empty;

    //XDocument doc = XDocument.Parse(stringifiedXML);
    //XDocument doc = XDocument.Parse(await Request.Content.ReadAsStringAsync()); 
    XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());

更新3

TToniの提案を使用し、二重引用符を一重引用符に置き換える:

...文字列全体をサーバーメソッドに取り込んでいます:

enter image description here

...しかし、まだ「ルート要素がありません」が表示されます:

System.Xml.XmlExceptionはユーザーコードによって処理されませんでしたHResult = -2146232000メッセージ=ルート要素がありません。 Source = System.Xml LineNumber = 0 LinePosition = 0 SourceUri = "" StackTrace:at System.Xml.XmlTextReaderImpl.Throw(Exception e)at System.Xml.XmlTextReaderImpl.ParseDocumentContent()at System.Xml.XmlTextReaderImpl.Read()at HandheldServerのSystem.Xml.Linq.XDocument.Load(Stream stream)のSystem.Xml.Linq.XDocument.Load(Stream stream、LoadOptions options)のSystem.Xml.Linq.XDocument.Load(XmlReader reader、LoadOptions options) Controllers.DeliveryItemsController.d__2.MoveNext()in c:\ HandheldServer\HandheldServer\Controllers\DeliveryItemsController.cs:line 66 InnerException:

もし私がまだ夢中でなかったら、これは私を夢中にさせるでしょう。現状では、どこに追いやられているのかよくわかりません。多くの雇用主は、運転されている人を探しています。多分これは彼らが意味することですか?

更新4

これを使用する:

XDocument doc = XDocument.Parse(stringifiedXML);

...これの代わりに:

XDocument doc = XDocument.Load(await Request.Content.ReadAsStreamAsync());

...「ルート要素がありません」エラーメッセージを解決しました。したがって、私はMarcinの答えを正解としてマークしました。

9
B. Clay Shannon

提供したサンプルXMLは、XDocumentで問題なく機能します。

_var stringifiedXML = @"<?xml version=""1.0""?>
    <LocateAndLaunch>
        <Tasks>Some Task</Tasks>
        <Locations>Some Location</Locations>
    </LocateAndLaunch>";

XDocument doc = XDocument.Parse(stringifiedXML);

var tasks = (string)doc.Root.Element("Tasks");
var locations = (string)doc.Root.Element("Locations");
_

したがって、問題はXDocumentではなく、await Request.Content.ReadAsStringAsync()にあります。

ReadAsStringAsync()が最初に必要なものを返すことを確認してください。

6
MarcinJuraszek

グーグルを通してこのページを見つけたが、それでも困惑している人のために。埋葬されたMSのおかげで答えを見つけたと思います 投稿

それは、以下を利用してストリームを最初にリセットすることにあります。

xmlStream.Seek(0, SeekOrigin.Begin);

読み取りの前にこれがないと、基本的にストリームの最後からロードを開始します。ストリームがなくなったため、ルート要素はありません。

9
Zexks Marquise

それが本当に文字列化されたXMLである場合、XML宣言は壊れています。バージョン番号は一重引用符または二重引用符で囲む必要があるため、<?xml version=1.0?>の代わりに<?xml version="1.0"?>または<?xml version='1.0'?>を実行してください。それはまたエラーIMOを説明するでしょう。

XML宣言の構文: http://www.w3.org/TR/REC-xml/#NT-XMLDecl

2
TToni

これは、以下のブログ投稿で説明されているように、カスタムパラメータバインディングを設定することで簡単に実現できます。 WebApiに生のxml投稿を使用する必要があるプロジェクトの1つで試しました

このブログエントリを確認してください

1
prasanth shenoy