استفاده از XQuery - قسمت اول
XQuery پیاده سازی شده در SQL Server با استانداردهای XQuery 1.0 و XPath 2.0 سازگار است. XQuery برای کار با نودهای مختلف یک سند XML، از XPath استفاده میکند. همچنین باید دقت داشت که این زبان به بزرگی و کوچکی حروف حساس است. در آن تمام واژههای کلیدی lowercase هستند و تمام متغیرها با علامت $ شروع میشوند.
ورودی و خروجی در XQuery
استاندارد XQuery از یک سری توابع ورودی مانند doc برای کار با یک سند و collection برای پردازش چندین سند کمک میگیرد. SQL Server از هیچکدام از این توابع پشتیبانی نمیکند. در اینجا از XQuery، به کمک متدهای نوع دادهای XML استفاده خواهد شد. این متدها شامل موارد ذیل هستند:
- query : یک xml را به عنوان ورودی گرفته و نهایتا یک خروجی XML دیگر را بر میگرداند.
- exist : خروجی bit دارد؛ true یا false.
- value : یک خروجی SQL Type را ارائه میدهد.
- nodes : خروجی جدولی دارد.
- modify : برای تغییر اطلاعات بکار میرود.
این موارد را در طی مثالهایی بررسی خواهیم کرد. بنابراین در ادامه نیاز است یک سند XML را که در طی مثالهای این قسمت مورد استفاده قرار خواهد گرفت، به شرح ذیل مدنظر داشته باشیم:
DECLARE @data XML SET @data = '<people> <person> <name> <givenName>name1</givenName> <familyName>lname1</familyName> </name> <age>33</age> <height>short</height> </person> <person> <name> <givenName>name2</givenName> <familyName>lname2</familyName> </name> <age>40</age> <height>short</height> </person> <person> <name> <givenName>name3</givenName> <familyName>lname3</familyName> </name> <age>30</age> <height>medium</height> </person> </people>'
همانطور که در قسمت قبل نیز ذکر شد، اگر اطلاعات شما در یک فایل XML قرار دارند، نحوهی خواندن آن به شکل یک فیلد XML با کمک openrowset مطابق دستورات زیر خواهد بود:
declare @data xml set @data = (select * from openrowset(bulk 'c:\path\data.xml', single_blob) as x)
بررسی متد query
متد query یک XQuery متنی را دریافت کرده، آنرا بر روی XML ورودی اجرا نموده و سپس یک خروجی XML دیگر را ارائه خواهد داد.
اگر به کتابهای استاندارد XQuery مراجعه کنید، به یک چنین کوئریهایی خواهید رسید:
for $p in doc("data.xml")/people/person where $p/age > 30 return $p/name/givenName/text()
SELECT @data.query(' for $p in /people/person where $p/age > 30 return $p/name/givenName/text() ')
بررسی متد value
در ادامه متد value را بررسی خواهیم کرد. در اینجا قصد داریم مقدار سن اولین شخص را نمایش دهیم:
SELECT @data.value('/people/person/age', 'int')
اگر کوئری فوق را اجرا کنیم با خطای ذیل مواجه خواهیم شد:
XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'
برای رفع این مشکل و اشاره به اولین شخص، میتوان از روش ذیل استفاده کرد:
SELECT @data.value('(/people/person/age)[1]', 'int')
تولید schema برای سند XML بحث جاری
با استفاده از برنامه Infer.exe مایکروسافت به سادگی میتوان برای یک سند XML، فایل Schema ایجاد کرد. این برنامه را از اینجا میتوانید دریافت کنید. پس از آن، اگر فرض کنیم اطلاعات سند XML مثال فوق در فایلی به نام people.xml ذخیره شدهاست، میتوان schema آنرا توسط دستور ذیل تولید کرد:
Infer.exe people.xml -o schema.xsd
که نهایتا چنین شکلی را خواهد داشت:
<xs:schema attributeFormDefault="unqualified" elementFormDefault="qualified" xmlns:xs="http://www.w3.org/2001/XMLSchema"> <xs:element name="people"> <xs:complexType> <xs:sequence> <xs:element maxOccurs="unbounded" name="person"> <xs:complexType> <xs:sequence> <xs:element name="name"> <xs:complexType> <xs:sequence> <xs:element name="givenName" type="xs:string" /> <xs:element name="familyName" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> <xs:element name="age" type="xs:unsignedByte" /> <xs:element name="height" type="xs:string" /> </xs:sequence> </xs:complexType> </xs:element> </xs:sequence> </xs:complexType> </xs:element> </xs:schema>
این خروجی را که اکنون به صورت یک فایل xsd، در کنار فایل xml معرفی شده به آن میتوان یافت، با استفاده از openrowset قابل بارگذاری است:
declare @schema xml set @schema = (select * from openrowset(bulk 'c:\path\schema_1.xsd', single_blob) as x)
سپس از این متغیر برای تعریف یک اسکیما کالکشن جدید استفاده خواهیم کرد:
CREATE XML SCHEMA COLLECTION poeple_xsd AS @schema
DECLARE @data XML(poeple_xsd) SET @data = 'مانند قبل با همان محتوایی که در ابتدای بحث عنوان شد'
SELECT @data.value('/people/person[1]/age', 'int')
XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xs:unsignedByte *'
مشکل کوئری نوشته در اینجا این است که زمانیکه نوع XML تعریف میشود، پیش فرض آن content است. یعنی در این حالت چندین root elemnt مجاز هستند. بنابراین person 1 درخواستی، میتواند چندین خروجی داشته باشد که در متد value مجاز نیست. این متد، پیش از اجرای کوئری، توسط parser تعیین اعتبار میشود و الزاما نیازی نیست تا حتما اجرا شده و سپس مشخص شود که چندین خروجی حاصل آن است.
اینبار تنها کاری که باید برای رفع مشکل گزارش شده انجام شود، تغییر content پیش فرض به document است:
DECLARE @data XML(document poeple_xsd)
sequences در XQuery
Sequences بسیار شبیه به آرایهای از آیتمها هستند و منظور مجموعهای از نودها یا مقادیر آنها است. برای مثال به ورودی کوئریهای XQuery به شکل توالی از یک سند و به خروجی آنها همانند توالی صفر تا چند نود نگاه کنید.
DECLARE @x XML SET @x='' SELECT @x.query( ' 1,2 (: 1,2 :) ')
همچنین باید دقت داشت که این توالی خطی تفسیر میشود.
DECLARE @x XML SET @x='' SELECT @x.query( ' for $x in (1,2,3) for $y in (4,5) return ($x,$y) ')
به علاوه در SQL Server امکان تعریف Heterogeneous sequences وجود ندارد؛ به عبارتی توالی بین مقادیر و نودها مجاز نیست. برای مثال اگر کوئری زیر را اجرا کنید:
DECLARE @x XML SET @x='' SELECT @x.query( ' 1, <node/> ')
XQuery [query()]: Heterogeneous sequences are not allowed: found 'xs:integer' and 'element(node,xdt:untyped)'
- اما ... Gulp جاوا اسکریپتی اساسا وابستگی خاصی به فناوریهای سمت سرور ندارد. در اینجا فقط نحوهی مسیردهی این پوشهها مهم هستند (و Task runner آن فقط به این مسایل دقت میکند):
var appFolder = "./app"; var outFolder = "wwwroot";
gulpfile.js systemjs.config.js --app --wwwroot
- 12 ساعت قبل
- دیروز
- لحظاتی پیش
- ...
public class RelativeTimeCalculator { const int SECOND = 1; const int MINUTE = 60 * SECOND; const int HOUR = 60 * MINUTE; const int DAY = 24 * HOUR; const int MONTH = 30 * DAY; public static string Calculate(DateTime dateTime) { var ts = new TimeSpan(DateTime.Now.Ticks - dateTime.Ticks); double delta = Math.Abs(ts.TotalSeconds); if (delta < 1 * MINUTE) { return ts.Seconds == 1 ? "لحظه ای قبل" : ts.Seconds + " ثانیه قبل"; } if (delta < 2 * MINUTE) { return "یک دقیقه قبل"; } if (delta < 45 * MINUTE) { return ts.Minutes + " دقیقه قبل"; } if (delta < 90 * MINUTE) { return "یک ساعت قبل"; } if (delta < 24 * HOUR) { return ts.Hours + " ساعت قبل"; } if (delta < 48 * HOUR) { return "دیروز"; } if (delta < 30 * DAY) { return ts.Days + " روز قبل"; } if (delta < 12 * MONTH) { int months = Convert.ToInt32(Math.Floor((double)ts.Days / 30)); return months <= 1 ? "یک ماه قبل" : months + " ماه قبل"; } int years = Convert.ToInt32(Math.Floor((double)ts.Days / 365)); return years <= 1 ? "یک سال قبل" : years + " سال قبل"; } }
var relativeTime=RelativeTimeCalculator.Calculate(DateTime.Now.AddMinutes(-10));
نظر سنجی در مورد نحوه تکمیل پروژه
به نظر دوستان بهتر است است کدام یک از فریمورکهای زیر را مورد استفاده قرار دهم تا در آینده هم به توان از این قالب به عنوان یک فریمورک برای کارهای روزمره استفاده کنیم؟ واقعا نسبت به این موضوع وسواس شدیدی دارم .
- Kendo UI
- AngularJs
- AngularJs X-editable
- یا روش معمول و استفاده از HTML خالی
Unit Testing در AngularJS
JavaScript is a dynamically typed language which comes with great power of expression, but it also comes with almost no help from the compiler. For this reason we feel very strongly that any code written in JavaScript needs to come with a strong set of tests. We have built many features into Angular which make testing your Angular applications easy. With Angular, there is no excuse for not testing.
"SoReL-20M" (short for Sophos-ReversingLabs – 20 Million), as it's called, is a dataset containing metadata, labels, and features for 20 million Windows Portable Executable (.PE) files, including 10 million disarmed malware samples, with the goal of devising machine-learning approaches for better malware detection capabilities.
- Custom tasks with default contextType via tasks.vs.json are broken in Open Folder.
- No snapshot created for C++ native code in Memory Usage tool in the Diagnostic Tools window while debugging.
- Crash in VS 16.1.0 when pressing the link "search online".
- Fixed the issue where sometimes certain features (i.e. Find All References) in LiveShare guest session do not work.
- Fixed an issue where the devenv.exe process could hang around after shutdown of Visual Studio for up to 30 seconds.