PDA

View Full Version : سوال: مشکل کامپایل یک تیکه



zahra_tulips
جمعه 19 مهر 1387, 14:00 عصر
چه مشکلی می تونه وجود داشته باشه وقتی که :

اجرای کلی برنامه (run) جواب اشتباه میده ولی اجرای خط به خط برنامه (step over) جواب درست!!!

این کد این مشکل رو داره که تو محیط توسعه ی visual studio 2005 و به زبان #C این مشکل رو پیدا کرده.




using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.XPath;
using System.Xml;
namespace testxml
{
class Program
{
static void Main(string[] args)
{
XmlDocument xmlpath = new XmlDocument();
xmlpath.Load("XpathTest.xml");
string a;
XmlNodeList xe;
XmlElement root = xmlpath.DocumentElement;
xe = root.SelectNodes("/bookstore/book")
root.RemoveAll();

for (int i = 0; i < xe.Count; i++)
{
root.InnerXml += xe.Item(i).InnerXml;
}

root.InnerXml = "<root>" + root.InnerXml + "</root>";

XmlDocument xm = new XmlDocument()
xm.InnerXml = root.InnerXml;
xm.Save("stor.xml");

}
}
}



این هم فایل XML که استفاده شده :



<?xml version="1.0" encoding="utf-8" ?>
<bookstore>
<book genre="autobiography" publicationdate="1981" ISBN="1-861003-11-0">
<title>The Autobiography of Benjamin Franklin</title>
<author>
<first-name>Benjamin</first-name>
<last-name>Franklin</last-name>
</author>
<price>8.99</price>
</book>
<book genre="novel" publicationdate="1967" ISBN="0-201-63361-2">
<title>The Confidence Man</title>
<author>
<first-name>Herman</first-name>
<last-name>Melville</last-name>
</author>
<price>11.99</price>
</book>
<book genre="philosophy" publicationdate="1991" ISBN="1-861001-57-6">
<title>The Gorgias</title>
<author>
<name>Plato</name>
</author>
<price>9.99</price>
</book>
</bookstore>

SMRAH1
شنبه 20 مهر 1387, 07:04 صبح
سلام

دوست من اشکال در خطوط :

XmlElement root = xmlpath.DocumentElement;
xe = root.SelectNodes("/bookstore/book");
root.RemoveAll();
است که بعد از این خطوط xe.Count صفر می باشد.به نظر می رسد که بعد RemoveAll در root،مقادیر xe هم پاک می شود.در اسناد MSDN در این رابطه تاکید کرده است که در صورت تغییر در root نباید انتظار تغییر در xe را داشته باشد ولی هیچ کجا صریحا به استقلال این دو اشاره نکرده است!!! به عبارت دیگر احتمالا بین داده های این دو رابطه وجود دارد(لطفا دوستان راهنمایی بفرمانند).

اما چرا در step Over این مشکل وجود ندارد؟ اول تست کردم و. دیدم شما درست می گویید.ولی بعد که دقیق تر شدم متوجه چیز جالبی شدم.شما Step Over رو به این شکل اجرا کنید.بعد از ورود به step Over،خط به خط برنامه را اجرا کنید (با هر فاصله زمانی که می خواهد در هر خط توقف کنید) با حفظ فقط یک شرط : debuger را مجبور نکنید که مقادیر متغیر ها را به شما نشان دهد! به عبارت دیگر نه به پنجره Locals بروید و نه حتی موس را روی پنجره کد برنامه حرکت دهید (قطعا مشاهده کرده اید که در حالت دیباگ،هر گاه موس را روی متغیری می برید مقدار و اشیای آن را به صورت شبه ToolTip نمایش می دهد).در این حالت خروجی همان است که در اجرای معمولی می بینید(xe.Count = 0).
احتمالا این یک باگ در دیباگر است و شاید نمایش مقادیر باعث می شود که یک کپی از داده ها ایجاد شود.این مطلب را به عدم روشن بودن رابطه root و xe بگذارید تا متوجه قضایا شوید.

در هر حال این برداشت من بوده و اگر دوستان دلیل دقیق را می دانند،«ما را نیز از جهل برهانند:چشمک:».

در ضمن برای رفع مشکل برنامه بهتر است از یک متغیر رشته ای قبل از خذف داده ها در root استفاده کنید یعنی چیزی شبیه این:

XmlDocument xmlpath = new XmlDocument();
xmlpath.Load("XpathTest.xml");
string a = "";

XmlElement root = xmlpath.DocumentElement;
XmlNodeList xe = root.SelectNodes("/bookstore/book");


for (int i = 0; i < xe.Count; i++)
{
a += xe.Item(i).InnerXml;
}
root.RemoveAll();
root.InnerXml = a;

root.InnerXml = "<root>" + root.InnerXml + "</root>";

XmlDocument xm = new XmlDocument();
xm.InnerXml = root.InnerXml;
xm.Save("stor.xml");

موفق باشید

zahra_tulips
شنبه 20 مهر 1387, 11:33 صبح
از جوابتون ممنونم. با متغیر رشته ای اما به یک صورت دیگه، جواب گرفتم اما هنوز جواب سوال قبلم رو متوجه نشدم که چرا این مشکل اصلاً باید ایجاد شه!! آیا این باگ برنامه ی منه یا مشکل کامپایلر #C !!!! و اینکه چه فرقی توی کامپایل به روش step over و به روش run هست که باعث ایجاد یه همچین تفاوتی میشه؟؟

این کد منه که با رشته مشکلش حل شده.


using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.XPath;
using System.Xml;
namespace testxml
{
classProgram
{
staticvoid Main(string[] args)
{
XmlDocument xmlpath = newXmlDocument();
xmlpath.Load("XpathTest.xml");
string a;
XmlNodeList xe;
XmlElement root = xmlpath.DocumentElement;
xe = root.SelectNodes("/bookstore/book/price");
root.RemoveAll();
string temp0 = "";
for (int i = 0; i < xe.Count; i++)
{
temp0 += xe.Item(i).OuterXml;
}
root.InnerXml = "<root>" + temp0 + "</root>";
XmlDocument xm = newXmlDocument();
xm.InnerXml = root.InnerXml;
xm.Save("stor.xml");
}
}
}

SMRAH1
شنبه 20 مهر 1387, 12:54 عصر
سلام

دوست من،این کدی که گذاشته بودید رو هم تست کردم،همون مشکل رو داره،یعنی در اجرایی معمولی،باعث میشه که مقدار خالی ارسال بشه.
خلاصه توضیحات اینه که در دو خط

xe = root.SelectNodes("/bookstore/book");
root.RemoveAll();
به محض فراخوانی متد RemoveAll شی root،گره ها یا Node های درون xe هم خالی میشه (توضیح دادم که MSDN تکلیف رو دقیقا مشخص نمی کنه که این دوتا با هم ارتباط دارند یا ندارند).البته دلیل اینکه در Step Over درسته اینکه که شما دیباگر رو مجبور به نمایش مقادیر متغیر ها می کنید و احتمالا اینجا یک کپی از این متغیر ها می گیره و در نتیجه با RemoveAll شی root ،مقادیر xe حذف نمیشه.اگر اینطور باشه،این نشاندهنده یک باگ در دیباگر ویژوال استودیو است.
البته این نکته ها حدسیات منه و ممکنه غلط باشه.اگر دوستان علت دقیق رو می دونند لطفا راهنمایی کنند.

موفق باشید