XDocument producing invalid XML - linq

I have this code
Dim doc As XDocument = New XDocument( _
New XDeclaration("1.0", "utf-8", "yes"), _
New XElement("transaction", _
New XElement("realm", wcRealm), _
New XElement("password", wcPassword), _
New XElement("confirmation_email", wcConfEmail), _
New XElement("force_subscribe", wcSubscribe), _
New XElement("optout", wcOptOut), _
New XElement("command", _
New XElement("type", wcType), _
New XElement("list_id", wcListId), _
From trans As DataRow In table.Rows _
Order By trans("last") _
Select New XElement("record", _
New XElement("email", trans("email")), _
New XElement("first", trans("first")), _
New XElement("last", trans("last")), _
New XElement("company", trans("company")), _
New XElement("address_1", trans("address_1")), _
New XElement("address_2", ""), _
New XElement("city", trans("city")), _
New XElement("state", trans("state")), _
New XElement("zip", trans("zip")), _
New XElement("country", trans("country")), _
New XElement("phone", trans("phone")), _
New XElement("fax", trans("fax")), _
New XElement("custom_source", trans("source")), _
New XElement("custom_vmail_expire_date", "")))))
'' # Save XML document at root.
doc.Save("c:\vj" & saveDate & ".xml")
which works fine a produces the proper XML file BUT I run it through a validator and get this error.
Sorry, I am unable to validate this document because on line 1 it contained one or more bytes that I cannot interpret as us-ascii (in other words, the bytes found are not valid values in the specified Character Encoding). Please check both the content of the file and the character encoding indication.
The error was: ascii "\xEF" does not map to Unicode
What could be causing that?

The problem is that you have an UTF-8 file that you are trying to validate as ASCII. Those 2 bytes are the unicode headers.

The validator doesn't support UTF8/UCS-2. Either save the file as ascii (which will break, as the xml says it's utf-8) or find a validator that was created within the last 5 years.
EDIT:
Note: If you want to save it as US Ascii, use new XDeclaration("1.0", "us-ascii", "yes")

The file is saved as UTF-8 with the byte-order-marker character at the start (this character begins with the octet 0xEF).
You validator for some reason seems not to like this character. Strictly speaking this character is whitespace and it is invalid to have whitespace preceeding the XML declaration. However, most parsers I know will skip it as being simply an indicator of unicode encoding and not treat it as content.

Related

How to look for _ in a string in a column and remove _ in SAS

I am trying to do an if statement where it finds all the observations in the column "CarBrands" that have an underscore _ in the string (it's a character), and if it has the _, then I want to remove it. How do I do this? Thanks.
You can use the FIND function to check if a string contains the underscore. Then with the COMPRESS function, you can remove the underscore.
For example;
data work.ds;
input mystring $;
datalines;
mytext
my_text
;
run;
data work.ds_1;
set work.ds;
if find(mystring,'_') > 0 then mystring = compress(mystring,'_');
else mystring = mystring;
run;
See also:
https://sasexamplecode.com/find-a-substring-in-sas/
https://documentation.sas.com/?docsetId=lefunctionsref&docsetTarget=n0fcshr0ir3h73n1b845c4aq58hz.htm&docsetVersion=9.4&locale=en

Arabic word search tool [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I want to make a search tool to find a specific word in the Arabic language that i can find just the word for example:
ذهب الولد إلى المدرسة من البيت و منهم الى البيت
If I try to find the word "من", the code not only finds the word "من", but also finds part of the word " منهم". I don't want the program to do that. I want to find the word " من" and every word like it and make whole case to the word.
To make things more clear (using an English example), if I were to search for the word 'to' in the following sentence, I would only want whole words to be found, and not words that contain the word 'to' such as 'toward' to become a part of the result.
Sentence: I want to go towards the bus.
Searches like this can be frustrating. What I usually do is to add a space at the front of the search string and also at the end and then search for SearchString.
So... "I want to go towards the bus." becomes " I want to go towards the bus. ". Then I search for " to ". The problem with this method is that punctuation can cause a problem. For example, if you wanted to search for "bus", you would use:
" I want to go towards the bus. " and search for " bus ". This would not be found because there is punctuation after the word bus.
I would encourage you to use regular expressions for this functionality. VB6 does not have regular expressions built in, but you can use the Microsoft VBScript Regular Expressions functionality to accomplish this. Please take a look at this page to help you get started: http://support.microsoft.com/kb/818802
Edit based on your comment
You have this line of code:
pos = InStr(start_at, txtBody.Text, target)
try changing that line to this:
pos = InStr(start_at, " " & txtBody.Text & " ", " " & target & " ", vbBinaryCompare)
By adding spaces in the code, you are actually checking for (space)target(space). So that you don't miss potential matches at the beginning or end of txtBody.Text, spaces are added there (for comparison purposes only). By adding vbBinaryCompare, InStr will now perform a case sensitive search.
The only completely thorough way of doing this is to use the Instr() function, and then check that the next character is a punctuation character, a newline, or the word is at the end of the string, e.g.
Option Explicit
Private Declare Function GetStringTypeW Lib "Kernel32.dll" ( _
ByVal dwInfoType As Long, _
ByVal lpSrcStr As Long, _
ByVal cchSrc As Long, _
ByRef lpCharType As Integer _
) As Long
Private Const CT_CTYPE1 As Long = &H1
Private Const C1_UPPER As Long = &H1 ' Uppercase
Private Const C1_LOWER As Long = &H2 ' Lowercase
Private Const C1_DIGIT As Long = &H4 ' Decimal digits
Private Const C1_SPACE As Long = &H8 ' Space characters
Private Const C1_PUNCT As Long = &H10 ' Punctuation
Private Const C1_CNTRL As Long = &H20 ' Control characters
Private Const C1_BLANK As Long = &H40 ' Blank characters
Private Const C1_XDIGIT As Long = &H80 ' Hexadecimal digits
Private Const C1_ALPHA As Long = &H100 ' Any linguistic character: alphabetical, syllabary, or ideographic
Private Const C1_DEFINED As Long = &H200 ' A defined character, but not one of the other C1_* types
Function FindFullWord(ByVal in_lStartPos As Long, ByRef in_sText As String, ByRef in_sSearch As String, Optional ByVal in_eCompareMethod As VbCompareMethod = vbBinaryCompare) As Long
Dim nLenText As Long
Dim nLenSearch As Long
Dim sNextChar As String
Dim iCharType As Integer
FindFullWord = InStr(in_lStartPos, in_sText, in_sSearch, in_eCompareMethod)
' Did we find the search string in the text?
If (FindFullWord > 0) Then
' Save the length of the text.
nLenText = Len(in_sText)
nLenSearch = Len(in_sSearch)
Do
' Does this position mean that the search is the end of the string?
If (FindFullWord + nLenSearch - 1) = nLenText Then
' If so, we can exit now - there are no following characters.
Exit Function
End If
' Look at the next character.
sNextChar = Mid$(in_sText, FindFullWord + nLenSearch, 1)
' Is this next char a space, punctuation character, or a blank?
If (GetStringTypeW(CT_CTYPE1, StrPtr(sNextChar), 1, iCharType)) Then
If (iCharType And C1_SPACE) = C1_SPACE Then
Exit Function
ElseIf (iCharType And C1_PUNCT) = C1_PUNCT Then
Exit Function
ElseIf (iCharType And C1_BLANK) = C1_BLANK Then
Exit Function
End If
End If
' Find the position of the search string in the text.
FindFullWord = InStr(FindFullWord + nLenSearch, in_sText, in_sSearch, in_eCompareMethod)
Loop Until FindFullWord = 0
End If
End Function
I originally started doing a test for every character which could follow a word and would not be part of that word, but the code started getting very long. And, of course, I know absolutely nothing about Arabic. So I wondered whether there was a standard way of finding out the general "type" of a character, regardless of language. And as it happens, there was.
The GetStringTypeW() method is documented in the Win32 documentation, and essentially can retrieve information about all the characters in a string. In my case, I am only looking at the character which follows the search word in a piece of text. The variable iCharType which returns the value from the string is a bitfield, and contains a number of values OR'ed together. I am using the AND operator to isolate just the values I am interested in.

Save mail to msg file using EWS API

I'm using Exchange Web Services Managed API 1.1 to connect to Exchange server 2010 and then find out new emails received. Now I want to save a copy of the .msg file to a folder on the disk.
I do not want to use any paid third party to integrate.
Any help will be appreciated.
If you are happy to save into the .eml format instead, it can be done very easily just using EWS and no third party libraries. The .eml file will contain all the same information and can be opened by Outlook in the same way as .msg (and also by other programs).
message.Load(new PropertySet(ItemSchema.MimeContent));
MimeContent mc = message.MimeContent;
FileStream fs = new FileStream("c:\test.eml", FileMode.Create);
fs.Write(mc.Content, 0, mc.Content.Length);
fs.Close();
Cleaned up code:
message.Load(new PropertySet(ItemSchema.MimeContent));
var mimeContent = message.MimeContent;
using (var fileStream = new FileStream(#"C:\Test.eml", FileMode.Create))
{
fileStream.Write(mimeContent.Content, 0, mimeContent.Content.Length);
}
There is no native support for MSG files using EWS. It's strictly an Outlook format.
The MSG spec is published at http://msdn.microsoft.com/en-us/library/cc463912%28EXCHG.80%29.aspx. It's a little complicated to understand, but do-able. You would need to pull down all of the properties for the message and then serialize it into an OLE structured file format. It's not an easy task.
In the end, you are probably better off going with a 3rd party library otherwise it might be a big task to accomplish.
You can easily access the MIME contents of the message through message.MimeContent and save the message as an EML file. The latest (2013 and 2016) versions of Outlook will be able to open EML files directly.
message.Load(new PropertySet(ItemSchema.MimeContent));
MimeContent mimcon = message.MimeContent;
FileStream fStream = new FileStream("c:\test.eml", FileMode.Create);
fStream.Write(mimcon.Content, 0, mimcon.Content.Length);
fStream.Close();
If you still need to convert to the MSG format, you have a few options:
MSG file format is documented - it is an OLE store (IStorage) file. See https://msdn.microsoft.com/en-us/library/cc463912(v=exchg.80).aspx
Use a third party MSG file wrapper, such as the one from Independentsoft: http://www.independentsoft.de/msg/index.html. Setting all properties that Outlook expects can be challenging.
Convert EML file to MSG directly using Redemption (I am its author):
set Session = CreateObject("Redemption.RDOSession") set Msg = Session.CreateMessageFromMsgFile("c:\test.msg") Msg.Import("c:\test.eml", 1024) Msg.Save
Keep in mind that MIME won't preserve all MAPI specific properties. You can use the Fast Transfer Stream (FTS) format used by the ExportItems EWS operation (which, just like the MSG format, preserves most MAPI properties). The FTS data can then be converted (without any loss of fidelity) to the MSG format using Redemption (I am its author) - RDOSession.CreateMessageFromMsgFile / RDOMail.Import(..., olFTS) / RDOMail.Save
RDOSession session = new RDOSession(); RDOMail msg = session.CreateMessageFromMsgFile(#"c:\temp\test.msg"); msg.Import(#"c:\temp\test.fts", rdoSaveAsType.olFTS); msg.Save();
This suggestion was posted as a comment by #mack, but I think it deserves its own place as an answer, if for no other reason than formatting and readability of answers vs. comments.
using (FileStream fileStream =
File.Open(#"C:\message.eml", FileMode.Create, FileAccess.Write))
{
message.Load(new PropertySet(ItemSchema.MimeContent));
MimeContent mc = message.MimeContent;
fileStream.Write(mc.Content, 0, mc.Content.Length);
}
If eml format is an option and php is the language use base64_decode on the Mimencontent before save on file.
If using https://github.com/Heartspring/Exchange-Web-Services-for-PHP or https://github.com/hatsuseno/Exchange-Web-Services-for-PHP need to add
$newmessage->mc = $messageobj->MimeContent->_;
on line 245 or 247.
This is how I solved the problem to download from EWS the email message in .eml format via vbs code
' This is the function that retrieves the message:
function CreaMailMsg(ItemId,ChangeKey)
Dim MailMsg
Dim GetItemSOAP,GetItemResponse,Content
LogFile.WriteLine (Now() & "-" & ":CreaMailMsg:ID:" & ItemId)
GetItemSOAP=ReadTemplate("GetItemMsg.xml")
GetItemSOAP=Replace(GetItemSOAP, "<!--ITEMID-->", ItemId)
GetItemSOAP=Replace(GetItemSOAP, "<!--ITEMCHANGEKEY-->", ChangeKey)
LogFile.WriteLine (Now() & ":GetItemSOAP:" & GetItemSOAP)
set GetItemResponse=SendSOAP(GetItemSOAP,TARGETURL,"",USERNAME,PASSWORD)
' Check we got a Success response
if not IsResponseSuccess(GetItemResponse, "m:GetItemResponseMessage","ResponseClass") then
LogFile.WriteLine (Now() & "-" & ":ERRORE:Fallita GetItemMsg:" & GetItemResponse.xml)
Chiusura 1
end if
' LogFile.WriteLine (Now() & "-" & ":DEBUG:riuscita GetItemMsg:" & GetItemResponse.xml)
Content = GetItemResponse.documentElement.getElementsByTagName("t:MimeContent").Item(0).Text
' LogFile.WriteLine (Now() & ":Contenuto MIME" & Content)
CreaMailMsg = WriteAttach2File(Content,"OriginaryMsg.eml")
' MailMsg.close
CreaMailMsg = true
end function
'###########################################################################
' These are the functions the save the message in .eml format
'###########################################################################
function WriteAttach2File(Content,nomeAttach)
Dim oNode,oXML,Base64Decode
' Read the contents Base64 encoded and Write a file
set oXML=CreateObject("MSXML2.DOMDocument")
set oNode=oXML.CreateElement("base64")
oNode.DataType="bin.base64"
oNode.Text = Content
Base64Decode = Stream_Binary2String(oNode.nodeTypedValue,nomeAttach)
Set oNode = Nothing
Set oXML = Nothing
end function
'###########################################################################
function Stream_Binary2String(binary,nomeAttach)
Const adTypeText = 2
Const adTypeBinary = 1
Dim BinaryStream
Set BinaryStream=CreateObject("ADODB.Stream")
BinaryStream.Type=adTypeBinary' Binary
BinaryStream.Open
BinaryStream.Write binary
BinaryStream.Position=0
BinaryStream.Type=adTypeText
BinaryStream.CharSet = "us-ascii"
Stream_Binary2String=BinaryStream.ReadText
'msgbox Stream_Binary2String
BinaryStream.SaveToFile ShareName & "\" & nomeAttach,2
Set BinaryStream=Nothing
end function
If you are going from Outlook's EntryID via VSTO (Hex) to EwsID, you need to look here: http://bernhardelbl.wordpress.com/2013/04/15/converting-entryid-to-ewsid-using-exchange-web-services-ews/
Saved me. I kept getting a "Data is corrupt." message.
You can download all the attachments using EWS API and C# . Below is the example given:
byte[][] btAttachments = new byte[3][]; //To store 3 attachment
if (item.HasAttachments) {
EmailMessage message = EmailMessage.Bind(objService, new ItemId(item.Id.UniqueId.ToString()), new PropertySet(BasePropertySet.IdOnly, ItemSchema.Attachments));
noOfAttachment = message.Attachments.Count;
// Iterate through the attachments collection and load each attachment.
foreach(Attachment attachment in message.Attachments)
{
if (attachment is FileAttachment)
{
FileAttachment fileAttachment = attachment as FileAttachment;
// Load the file attachment into memory and print out its file name.
fileAttachment.Load();
//Get the Attachment as bytes
if (i < 3) {
btAttachments[i] = fileAttachment.Content;
i++;
}
}
// Attachment is an item attachment.
else
{
// Load attachment into memory and write out the subject.
ItemAttachment itemAttachment = attachment as ItemAttachment;
itemAttachment.Load(new PropertySet(EmailMessageSchema.MimeContent));
MimeContent mc = itemAttachment.Item.MimeContent;
if (i < 3) {
btAttachments[i] = mc.Content;
i++;
}
}
}
}
Above code converts all the attachment into bytes. Once you have bytes, you can convert bytes into your required format.
To Convert bytes into files and save in the disk follow the below links:
Write bytes to file
http://www.digitalcoding.com/Code-Snippets/C-Sharp/C-Code-Snippet-Save-byte-array-to-file.html

String to Function Name in Visual Studio

I saw in a screencast a while ago (since forgotten which, probably a Kata) where a person was writing out a unit test but wrote something like this:
public "return zero for an all gutter game"
Then they magically turned it into
public returnZeroForAnAllGutterGame
Is there a plugin for this or just a simple way to do a template that gets fired off on a key stroke?
I googled around and just couldn't think of a good way to type in a search to get what I wanted.
I couldn't find the plugin or macro you refer to, but I did create a macro that will work nicely!
First, to install do the following:
Press Alt+F11
Expand MyMacros
Open the EnvironmentEvents module
Past the code into the module (code is found at the end of this post)
Close the macro editor
To use the macro:
Press ` (grave key).
Next press "
Type the words you desire
End by typing "`
Watch the magic happen!
NOTE: You could just start typing a sting value then latter add the grave symbols before and after and it will still work.
The macro will remove spaces and then PascalCase the entire set of words. It also strips out single and double quotes. Lastly, it will convert commas to underscores if you want to use the naming convention suggested by Roy Osherove (The Art of Unit Testing, p. 211):
MethodUnderTest_Scenario_Behavior()
Examples:
public void `"return zero for an all gutter game"`
public void `"LoadMainParts, when materials files are valid, will return a list of parts sorted by sequential item number ascending"`
...will turn into this (after the second ` press):
public void ReturnZeroForAnAllGutterGame
public void LoadMainParts_WhenMaterialsFilesAreValid_WillReturnAListOfPartsSortedBySequentialItemNumberAscending
The Macro:
...
Imports System.Text.RegularExpressions
...
Private isPascalCaseAndSpaceRemovalEnabled As Boolean
Private Function ConvertToPascalCase(ByVal value As String) As String
'apply ToUpper on letters preceeded by a space, double quotes, or a comma'
Dim pattern As String = "[ ,"",\,][a-z]"
value = Regex.Replace(value, _
pattern, _
Function(m) m.Value.ToUpper, _
RegexOptions.Singleline)
'replace commas with underscores'
value = value.Replace(",", "_")
'remove spaces, graves, double quotes, and single qoutes'
Dim removalCharacters As String() = {" ", "`", """", "'"}
For Each character In removalCharacters
value = value.Replace(character, "")
Next
Return value
End Function
Private Sub TextDocumentKeyPressEvents_AfterKeyPress(ByVal Keypress As String, _
ByVal Selection As EnvDTE.TextSelection, _
ByVal InStatementCompletion As Boolean) _
Handles TextDocumentKeyPressEvents.AfterKeyPress
If isPascalCaseAndSpaceRemovalEnabled AndAlso Keypress = "`" Then
Selection.SelectLine()
Dim pattern As String = "`""(.*)""`"
Dim substringToReplace As String = Regex.Match(Selection.Text, _
pattern, _
RegexOptions.Singleline).Value
Selection.ReplacePattern(pattern, _
ConvertToPascalCase(substringToReplace), _
vsFindOptions.vsFindOptionsRegularExpression)
Selection.MoveToPoint(Selection.BottomPoint)
isPascalCaseAndSpaceRemovalEnabled = False
CancelKeyPress = True
ElseIf Keypress = "`" Then
isPascalCaseAndSpaceRemovalEnabled = True
End If
End Sub
Feel free to tailor the code to your needs.

vbscript: convert unicode string to array of bytes

I have unicode string passed to vbscript procedure (not visual basic 6, but vbscript). I want to iterate unicode string char by char, get code for every symbol, truncate code to byte range [0..255] and create array of bytes.
This way new array of bytes should be twice smaller in memory compared to original unicode string. I am going save this array to file via ADODB.Stream object further
How can I convert unicode string to bytes array with symbol code truncated to byte range?
Thank you in advance!
Firstly, translating unicode to ascii will only work if your string only contains ascii characters. Since unicode contains ascii, it is just a matter of removing every second character.
Look up unicode on the internet for details.
EDIT: In unicode, every ascii character is proceeded with a NULL (0) byte. Remove this byte to convert the string to ASCII.
It seems there is no way to create array of bytes in vbs (though it's very straightforward in visual basic) -- all arrays are arrays of variants.
The task was to send binary stream from server to vbs script via string type. I have found the solution by creating Xml Document on the server with CDATA section that contains base64 coded array of bytes as string data.
Client (vbs) do the following:
set xmlDoc = CreateObject("Microsoft.XmlDom")
xmlDoc.loadXML(dataFromServer)
base64str = xmlDoc.DocumentElement.Text ' it's base64 coded binary stream
arrayOfBytes = decodeBase64(base64str)
Function decodeBase64(base64)
set dm = CreateObject("Microsoft.XMLDOM")
set el = dm.createElement("tmp")
el.DataType = "bin.base64"
el.Text = base64
decodeBase64 = el.NodeTypedValue
set dm = Nothing
End Function
This function creates an array of bytes:
' http://www.motobit.com/tips/detpg_binarytostring/
Function MultiByteToBinary(MultiByte)
'� 2000 Antonin Foller, http://www.motobit.com
' MultiByteToBinary converts multibyte string To real binary data (VT_UI1 | VT_ARRAY)
' Using recordset
Dim RS, LMultiByte, Binary
Const adLongVarBinary = 205
Set RS = CreateObject("ADODB.Recordset")
LMultiByte = LenB(MultiByte)
If LMultiByte>0 Then
RS.Fields.Append "mBinary", adLongVarBinary, LMultiByte
RS.Open
RS.AddNew
RS("mBinary").AppendChunk MultiByte & ChrB(0)
RS.Update
Binary = RS("mBinary").GetChunk(LMultiByte)
End If
MultiByteToBinary = Binary
End Function
This function creates a multi-byte string.
' http://www.motobit.com/help/regedit/pa26.htm
'Converts unicode string to a multibyte string
Function StringToMB(S)
Dim I, B
For I = 1 To Len(S)
B = B & ChrB(Asc(Mid(S, I, 1)))
Next
StringToMB = B
End Function

Resources