c # Разбор строки, содержащей специальные символы HTML как XElement - PullRequest
2 голосов
/ 28 марта 2011

Используя .NET c # на сервере + GWT на стороне клиента, у меня есть веб-форма, которая принимает пользовательский ввод, из которого я затем строю строку XML и сохраняю ее в базе данных. Затем мне нужно прочитать его обратно из базы данных, отправить на переносное устройство через tcp и проанализировать как XElement. Все работает хорошо, пока вы не скопируете и не вставите текст из Word или Excel, в этом случае, когда я пытаюсь сделать:

XElement.parse(str);

Выдает исключение:

'.', hexadecimal value 0x00, is an invalid character. Line 132, position 111.

Пример символа, который может вызвать эту проблему - правильный символ апостроф (0x2019). Теперь может быть целый набор специальных символов, возможно скопированных из Excel / Word и т. Д. Каков наилучший способ справиться с этим? Вот как я строю строку из потока:

protected CallResult callUsingSocketClass(string methodName, params Action<CallParameters>[] addParameters)

{ WebServicesClient.Debug.DebugMessage (WebServicesClient.Debug.MASK_ENTRY_EXIT, "Вызов ++ ({0}, ...)", имя-метода);

        if (this.OnTransferring != null)
        {
            if (!this.OnTransferring())
            {
                return null;
            }
        }
        CallParameters parameters = new CallParameters(this, methodName);
        foreach (var addParameter in addParameters)
        {
            addParameter(parameters);
        }

        string post = this.CreatePost(parameters);
        WebServicesClient.Debug.DebugMessage(WebServicesClient.Debug.MASK_RPC_CALL, "RPC(Method={0}, host={1}, port={2}, post='{3}')", methodName, this.Host, this.Port, post);
        byte[] postBytes = Encoding.UTF8.GetBytes(post);

        //
        // Send the request and wait for the reply.
        //
        char[] replyContentChars = null;
        for (int attempts = 0; attempts < 3; attempts++)
        {
            Socket socket = null;
            try
            {
                WebServicesClient.Debug.DebugMessage(WebServicesClient.Debug.MASK_RPC_CALL, "RPC - creating socket for RPC call...");
                if (this.OnTransferring != null)
                {
                    if (!this.OnTransferring())
                    {
                        return null;
                    }
                }
                string hostID = this.Host;
                if (this.HostIPAddress != null)
                {
                    hostID = this.HostIPAddress;
                }
                using (socket = this.connectToServer(hostID, this.Port))
                {
                    if (socket == null)
                    {
                        return null;
                    }
                    if (this.OnTransferring != null)
                    {
                        if (!this.OnTransferring())
                        {
                            return null;
                        }
                    }
                    WebServicesClient.Debug.DebugMessage(WebServicesClient.Debug.MASK_RPC_CALL, "RPC - socket created!");
                    WebServicesClient.Debug.DebugMessage(WebServicesClient.Debug.MASK_RPC_CALL, "RPC - communicating with server...");
                    WebServicesClient.Debug.DebugMessage(WebServicesClient.Debug.MASK_RPC_CALL, "RPC - writing post...");
                    this.sendDataToServer(socket, postBytes);
                    int replyLength = -1;
                    if (this.OnTransferring != null)
                    {
                        if (!this.OnTransferring())
                        {
                            return null;
                        }
                    }
                    WebServicesClient.Debug.DebugMessage(WebServicesClient.Debug.MASK_RPC_CALL, "RPC - reading reply...");
                    using (var reader = this.receiveStreamFromServer(socket))
                    {
                        if (this.OnTransferring != null)
                        {
                            if (!this.OnTransferring())
                            {
                                socket.Close();
                                socket = null;
                                return null;
                            }
                        }
                        for (; ; )
                        {
                            string lineRaw = reader.ReadLine().Trim();
                            string line = lineRaw.ToLowerInvariant();
                            if (line.StartsWith("content-length:"))
                            {
                                replyLength = int.Parse(line.Substring(15));
                            }
                            else if (line == "")
                            {
                                if (replyLength < 0)
                                {
                                    throw new InvalidOperationException("Reply hasn't specified content-length");
                                }
                                break;
                            }
                            else
                            {
                                if (this.CookieJar != null)
                                {
                                    this.CookieJar.ProcessFromServer(lineRaw);
                                }
                            }
                        }
                        // Content starts here
                        replyContentChars = new char[replyLength];
                        int replyRecv = 0;
                        do
                        {
                            int charsRecv = reader.Read(replyContentChars, replyRecv, replyLength - replyRecv);
                            if (charsRecv <= 0)
                            {
                                break;
                            }
                            replyRecv += charsRecv;
                        } while (replyRecv < replyLength);
                        //int charsRecv = reader.Read(replyContentChars, 0, replyLength);
                        if (replyRecv != replyLength)
                        {
                            untime.Logger.Logger.Error("Web Service call '{0}' received {1} bytes, header indicated {2} bytes", methodName, replyRecv, replyLength);
                            throw new InvalidOperationException(String.Format("Have not received all of reply data - received {0} bytes, expected {1}", replyRecv, replyLength));
                        }
                    }
                    socket.Close();
                    socket = null;
                }
            }
            catch (Exception e)
            {

                WebServicesClient.Debug.DebugMessage(WebServicesClient.Debug.MASK_RPC_CALL, "RPC - exception thrown - {0} [{1},{2}]", e.Message, e.Source, e.StackTrace);
            }
            finally
            {
                if (socket != null)
                {
                    socket.Close();
                    socket = null;
                }
            }
            if (replyContentChars != null)
            {
                break;
            }
            if (this.OnTransferring != null)
            {
                if (!this.OnTransferring())
                {
                    return null;
                }
            }
        }
        //
        // Verify that data has been received.
        //
        if (replyContentChars == null)
        {
            return null;
        }
        if (this.OnTransferring != null)
        {
            if (!this.OnTransferring())
            {
                return null;
            }
        }

        //
        // Process the received data.
        //
        string replyContent = new string(replyContentChars);
        WebServicesClient.Debug.DebugMessage(WebServicesClient.Debug.MASK_RPC_CALL, "RPC(Method={0}, replyContent='{1}')", methodName, replyContent);

        XElement xReplyContent = XElement.Parse(replyContent);

        var xReplyBody = xReplyContent.Element(nsSoap + "Body");
        var xFault = xReplyBody.Element(nsSoap + "Fault");
        if (xFault != null)
        {
            // Something has gone wrong on the server
            var xFaultCode = xFault.Element(nsSoap + "Code");
            var xFaultReason = xFault.Element(nsSoap + "Reason");
            untime.Logger.Logger.Error("Web Service call to method '{0}' failed: Code='{1}', Reason='{2}'", methodName, (string)xFaultCode, (string)xFaultReason);
            string faultCode = (string)xFaultCode;
            var codeParts = faultCode.Split(':');
            XmlQualifiedName xmlQualifiedName;
            if (codeParts.Length == 2)
            {
                xmlQualifiedName = new XmlQualifiedName(codeParts[1], codeParts[0]);
            }
            else
            {
                xmlQualifiedName = new XmlQualifiedName(faultCode);
            }
            throw new SoapException((string)xFaultReason, xmlQualifiedName);
        }

        var xResponse = xReplyBody.Element(this.nsArgs + (methodName + "Response"));
        var xResult = xResponse.Element(this.nsArgs + (methodName + "Result"));
        if (this.OnTransferring != null)
        {
            if (!this.OnTransferring())
            {
                return null;
            }
        }
        var result = new CallResult(xResult);
        return result;
    }

Ответы [ 2 ]

0 голосов
/ 29 марта 2011

Я нашел ответ на этот вопрос здесь:

http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/54c83f23-e579-48e9-9fbe-bc20232a02fc/

Идея состоит в том, чтобы либо убрать / заменить символы Юникода из ввода, либо использовать кодировку Юникод в XML, когдаконструируем его:

<?xml version="1.0" encoding="UTF-16"?>

В вышеприведенном посте принятый ответ предлагает следующий метод (вставка здесь), который работает нормально, но если вам нужно заменить определенные символы, вам придется добавить некоторый код, чтобы сделать это вдополнение:

      public string getRidOfUnprintablesAndUnicode ( string inpString )   
    {   
        string outputs = String.Empty;   
        for ( int jj = 0; jj < inpString.Length; jj++ )   
        {   
            char ch = inpString[ jj ];   
            if ( ( ( int )( byte )ch ) >= 32 & ( ( int )( byte )ch ) <= 128 )   
            {   
                outputs += ch;   
            }   
        }   
        return outputs;   
    } 
0 голосов
/ 28 марта 2011

System.Text.Encoding.UTF8, так как похоже, что Excel использует utf. преобразовать в вашу любимую кодировку.

...