37

基本的に次のような StringBuilder から XML ドキュメントを生成しています。

string.Format("<text><row>{0}</row><col>{1}</col><textHeight>{2}</textHeight><textWidth>{3}</textWidth><data>{4}</data><rotation>{5}</rotation></text>

後で、次のようなもの:

XmlDocument document = new XmlDocument();
document.LoadXml(xml);
XmlNodeList labelSetNodes = document.GetElementsByTagName("labels");
for (int index = 0; index < labelSetNodes.Count; index++)
{
    //do something
}

すべてのデータはデータベースから取得されます。最近、エラーでいくつかの問題が発生しました。

16 進値 0x00 は無効な文字です。行 1、位置 nnnnn

しかし、一貫していません。いくつかの「空白」データが機能する場合があります。「欠陥のある」データは一部の PC では機能しますが、他の PC では機能しません。

データベースでは、データは常に空白の文字列です。'null' になることはなく、XML ファイルでは として出力されます< data>< /data>。つまり、開始と終了の間に文字はありません。(ただし、「即時」ウィンドウから引っ張っているので、これが信頼できるかどうかはわかりません.vis studioであり、テキストパッドに貼り付けています)。

SQLサーバーのバージョン(2008年は失敗し、2005年は機能する)と照合にも違いがある可能性があります。これらのいずれかが原因である可能性があるかどうかわかりませんか?

しかし、まったく同じコードとデータが失敗することがあります。問題がどこにあるかについてのアイデアはありますか?

4

7 に答える 7

36

実際のデータやソースがなければ、何が問題なのかを診断するのは困難です。ただし、いくつかの提案を行うことができます。

  • Unicode NUL (0x00) は XML のすべてのバージョンで違法であり、検証パーサーはそれを含む入力を拒否する必要があります。
  • 上記にもかかわらず; 実際の検証されていない XML には、考えられるあらゆる種類のガベージ形式の悪いバイトが含まれる可能性があります。
  • XML 1.1 では、ゼロ幅および印刷不可の制御文字 (NUL を除く) を使用できるため、テキスト エディターで XML 1.1 ファイルを見て、含まれている文字を確認することはできません。

あなたが書いたことを考えると、データベース データを XML に変換するものは何でも壊れているのではないかと思います。XML 以外の文字を伝播しています。

非 XML 文字 (NUL、DEL、制御文字など) を含むいくつかのデータベース エントリを作成し、XML コンバータを実行します。XML をファイルに出力し、16 進エディタで確認します。これに XML 以外の文字が含まれている場合、コンバーターは壊れています。それを修正するか、できない場合は、そのような文字を含む出力を拒否するプリプロセッサを作成してください。

コンバーターの出力に問題がなければ、問題は XML コンシューマーにあります。XML 以外の文字がどこかに挿入されています。消費プロセスを別々のステップに分割し、各ステップで出力を調べて、悪い文字を導入しているものを絞り込む必要があります。

ファイルのエンコーディングを確認する (UTF-16 の場合)

更新: 私はちょうどこの例に出くわしました! 何が起きていたかというと、プロデューサーは XML を UTF16 としてエンコードしており、コンシューマーは UTF8 を想定していました。UTF16 はすべての ASCII 文字の上位バイトとして 0x00 を使用し、UTF8 は使用しないため、消費者はすべての 2 バイトを NUL として認識していました。私の場合、エンコーディングを変更できましたが、すべての XML ペイロードが BOM で始まることを提案しました。

于 2012-06-14T18:27:00.513 に答える
9

上記の Sonz の回答に追加すると、次のことがうまくいきました。

//Instead of 
XmlString.Replace("&#x0;", "[0x00]");
// use this
XmlString.Replace("\x00", "[0x00]");
于 2015-07-17T16:26:27.690 に答える
4

遅い答えのようなものとして:

レポートをアップロードするときに、SSRS ReportService2005.asmx でこの問題が発生しました。

    Public Shared Sub CreateReport(ByVal strFileNameAndPath As String, ByVal strReportName As String, ByVal strReportingPath As String, Optional ByVal bOverwrite As Boolean = True)
        Dim rs As SSRS_2005_Administration_WithFOA = New SSRS_2005_Administration_WithFOA
        rs.Credentials = ReportingServiceInterface.GetMyCredentials(strCredentialsURL)
        rs.Timeout = ReportingServiceInterface.iTimeout
        rs.Url = ReportingServiceInterface.strReportingServiceURL
        rs.UnsafeAuthenticatedConnectionSharing = True

        Dim btBuffer As Byte() = Nothing

        Dim rsWarnings As Warning() = Nothing
        Try
            Dim fstrStream As System.IO.FileStream = System.IO.File.OpenRead(strFileNameAndPath)
            btBuffer = New Byte(fstrStream.Length - 1) {}
            fstrStream.Read(btBuffer, 0, CInt(fstrStream.Length))
            fstrStream.Close()
        Catch ex As System.IO.IOException
            Throw New Exception(ex.Message)
        End Try

        Try
            rsWarnings = rs.CreateReport(strReportName, strReportingPath, bOverwrite, btBuffer, Nothing)

            If Not (rsWarnings Is Nothing) Then
                Dim warning As Warning
                For Each warning In rsWarnings
                    Log(warning.Message)
                Next warning
            Else
                Log("Report: {0} created successfully with no warnings", strReportName)
            End If

        Catch ex As System.Web.Services.Protocols.SoapException
            Log(ex.Detail.InnerXml.ToString())
        Catch ex As Exception
            Log("Error at creating report. Invalid server name/timeout?" + vbCrLf + vbCrLf + "Error Description: " + vbCrLf + ex.Message)
            Console.ReadKey()
            System.Environment.Exit(1)
        End Try
    End Sub ' End Function CreateThisReport

この問題は、RDL (XML) ファイルよりも 1 バイト以上大きいバイト配列を割り当てると発生します。

具体的には、C#からvb.netへのコンバーターを使用しました。

  btBuffer = new byte[fstrStream.Length];

の中へ

  btBuffer = New Byte(fstrStream.Length) {}

しかし、C# では数字が配列内の要素数を表し、VB.NET ではその数字が配列の上限を表すため、余分なバイトがあり、このエラーが発生しました。

したがって、問題の解決策は次のとおりです。

  btBuffer = New Byte(fstrStream.Length - 1) {}
于 2013-11-15T08:37:32.390 に答える
4

Web.config ファイルにいくつかの Unicode データ (ヒンディー語) を保存し、それを "Unicode" エンコーディングで保存すると、ASP.NET アプリケーションでも同じエラーが発生します。

「UTF-8」エンコーディングで Web.config ファイルを保存したときのエラーを修正しました。

于 2013-04-17T05:24:16.543 に答える