XmlReader пропускает половину данных, отправляемых веб-сервису - PullRequest
1 голос
/ 18 июня 2010

У меня есть веб-сервис, который имеет один метод:

[WebMethod]
public bool SyncUserData(string userxml)

xml - это серия записей пользователя, и я использую XmlReader для чтения и обработки данных.

Когда я вызываю веб-сервис с 2000 записями, он обрабатывает 2000 записей. Когда мой клиент вызывает его с тем же xml, он обрабатывает 1000 записей. Обрабатывает все остальные записи.

Кто-нибудь имеет опыт работы с подобными проблемами? Я думаю, что это проблема с кодировкой, но я попытался отправить данные в службу как ASCII, ISO-8859-1 и т. Д. В своих тестах и ​​не могу воссоздать.

Любая помощь высоко ценится.

Это телефонный код:

while (userXml.Read())
{

    if (userXml.Name == NODE_NAME_FILE_NAME && userXml.NodeType == XmlNodeType.Element)
    {
        _importFilename = userXml.ReadString();
    }

    if (userXml.Name == NODE_NAME_USER && userXml.NodeType == XmlNodeType.Element)
    {
        ProcessUser(userXml);
    }
}

и вот что processUser делает с xml reader

private void ProcessUser(XmlReader userXml)
{
    _usersinfeed++;
    XmlDocument user = new XmlDocument();
    user.LoadXml(userXml.ReadOuterXml());
     ...

}

1 Ответ

1 голос
/ 18 июня 2010

Что вас кусает, так это побочный эффект ReadOuterXml - он, скорее всего, продвигает текущую позицию XmlReader - но затем в вашем цикле while (userXml.Read()) вы продвигаете его снова - пропуская один элемент xml в процессе.

Существуют различные способы решения этой проблемы, но самым простым и чистым было бы не использовать XmlReader. Это вариант?

Более простой способ обработки xml - это Linq to Xml:

public static void Main()
{
    SyncUserData(@"
    <doc>
    <filename>test</filename>
    <user>Someone</user>
    <user>Someone2</user>

    <filename>testA</filename>
    <user>Someone else</user>
    <user>Someone else2</user>
    </doc>
    ");
}

const string  NODE_NAME_FILE_NAME = "filename";
const string  NODE_NAME_USER = "user";

static string _importFilename;
static int _usersinfeed;

public static bool SyncUserData(string userxml) {
    foreach(XElement el in XDocument.Parse(userxml).Descendants()) {
        //or: XDocument.Parse(userxml).Root.Elements() -- this depends on your document

        if (el.Name == NODE_NAME_FILE_NAME)
            _importFilename = el.Value;
        if (el.Name == NODE_NAME_USER)
            ProcessUser(el);
    }
    return true;
}

private static void ProcessUser(XElement el)
{
    _usersinfeed++;
    Console.WriteLine("User:{0}, file:{1}\n{2}\n",_usersinfeed,_importFilename,el);
    //you probably don't need the following anymore
    //XmlDocument user = new XmlDocument();
    //user.LoadXml(el.CreateReader());

    //...
}

Какие выходы:

User:1, file:test
<user>Someone</user>

User:2, file:test
<user>Someone2</user>

User:3, file:testA
<user>Someone else</user>

User:4, file:testA
<user>Someone else2</user>

Тем не менее, вы можете использовать сериализацию XML - это очень простой способ синтаксического анализа / генерации XML без лишних шаблонов, а также дает вам нативную структуру данных .NET для работы при загрузке! Затем вам просто нужен небольшой набор классов для определения структуры документа, и среда может автоматически создавать экземпляры из XML для вас без какого-либо ручного анализа кода. Однако не все синтаксисы XML поддаются этому.

...