how to ignore the last unknow characters at the end of the json string - iphone

{
education = (
{
school = {
id = 108102169223234;
name = psss;
};
type = College;
year = {
id = 142833822398097;
name = 2010;
};
}
);
}
!-- 1.2398s -->
the above leads me error as " NSLocalizedDescription=Unrecognised leading character"

not even close to valid JSON.. http://www.jsonlint.com/
Are you in charge of generating the feed? If so I would think it a lot better to fix the problem at the source than try re-factor your code to accommodate what ever that is that is getting returned.
Are you using a JSON framework in Xcode to parse that string?

Related

Build dynamic LINQ queries from a string - Use Reflection?

I have some word templates(maybe thousands). Each template has merge fields which will be filled from database. I don`t like writing separate code for every template and then build the application and deploy it whenever a template is changed or a field on the template is added!
Instead, I'm trying to define all merge fields in a separate xml file and for each field I want to write the "query" which will be called when needed. EX:
mergefield1 will call query "Case.Parties.FirstOrDefault.NameEn"
mergefield2 will call query "Case.CaseNumber"
mergefield3 will call query "Case.Documents.FirstOrDefault.DocumentContent.DocumentType"
Etc,
So, for a particular template I scan its merge fields, and for each merge field I take it`s "query definition" and make that request to database using EntityFramework and LINQ. Ex. it works for these queries: "TimeSlots.FirstOrDefault.StartDateTime" or
"Case.CaseNumber"
This will be an engine which will generate word documents and fill it with merge fields from xml. In addition, it will work for any new template or new merge field.
Now, I have worked a version using reflection.
public string GetColumnValueByObjectByName(Expression<Func<TEntity, bool>> filter = null, string objectName = "", string dllName = "", string objectID = "", string propertyName = "")
{
string objectDllName = objectName + ", " + dllName;
Type type = Type.GetType(objectDllName);
Guid oID = new Guid(objectID);
dynamic Entity = context.Set(type).Find(oID); // get Object by Type and ObjectID
string value = ""; //the value which will be filled with data from database
IEnumerable<string> linqMethods = typeof(System.Linq.Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public).Select(s => s.Name).ToList(); //get all linq methods and save them as list of strings
if (propertyName.Contains('.'))
{
string[] properies = propertyName.Split('.');
dynamic object1 = Entity;
IEnumerable<dynamic> Child = new List<dynamic>();
for (int i = 0; i < properies.Length; i++)
{
if (i < properies.Length - 1 && linqMethods.Contains(properies[i + 1]))
{
Child = type.GetProperty(properies[i]).GetValue(object1, null);
}
else if (linqMethods.Contains(properies[i]))
{
object1 = Child.Cast<object>().FirstOrDefault(); //for now works only with FirstOrDefault - Later it will be changed to work with ToList or other linq methods
type = object1.GetType();
}
else
{
if (linqMethods.Contains(properies[i]))
{
object1 = type.GetProperty(properies[i + 1]).GetValue(object1, null);
}
else
{
object1 = type.GetProperty(properies[i]).GetValue(object1, null);
}
type = object1.GetType();
}
}
value = object1.ToString(); //.StartDateTime.ToString();
}
return value;
}
I`m not sure if this is the best approach. Does anyone have a better suggestion, or maybe someone has already done something like this?
To shorten it: The idea is to make generic linq queries to database from a string like: "Case.Parties.FirstOrDefault.NameEn".
Your approach is very good. I have no doubt that it already works.
Another approach is using Expression Tree like #Egorikas have suggested.
Disclaimer: I'm the owner of the project Eval-Expression.NET
In short, this library allows you to evaluate almost any C# code at runtime (What you exactly want to do).
I would suggest you use my library instead. To keep the code:
More readable
Easier to support
Add some flexibility
Example
public string GetColumnValueByObjectByName(Expression<Func<TEntity, bool>> filter = null, string objectName = "", string dllName = "", string objectID = "", string propertyName = "")
{
string objectDllName = objectName + ", " + dllName;
Type type = Type.GetType(objectDllName);
Guid oID = new Guid(objectID);
object Entity = context.Set(type).Find(oID); // get Object by Type and ObjectID
var value = Eval.Execute("x." + propertyName, new { x = entity });
return value.ToString();
}
The library also allow you to use dynamic string with IQueryable
Wiki: LINQ-Dynamic

Talend: Split a data file into two flows/streams (header_info, data_rows)

Please, I don't need no solution, just a few hints on how-tos. Anyhow, here is the problem I am tackeling with:
I have a file (bloomberg answer file) which is built as follows:
we have a header part (I am only interested in the
START-OF-FIELDS[...]END-OF-FIELDS; varying amount of fields!)
then there is the data part: START-OF-DATA[...]END-OF-DATA. Where each row: unique_id|some_val|some_val|EXCH_CODE|ID_BB_GLOBAL|NAME|SECURITY_TYP|TICKER\n
Shortened example file:
START-OF-FILE
RUNDATE=20150921
PROGRAMFLAG=oneshot
DATEFORMAT=yyyymmdd_sep
FIRMNAME=dl111111
FILETYPE=pc
REPLYFILENAME=r150921020044_20426_01_00
SECMASTER=yes
DERIVED=yes
CREDITRISK=yes
USERNUMBER=1111111
WS=0
SN=111111
CLOSINGVALUES=yes
SECID=BB_GLOBAL
PROGRAMNAME=getdata
START-OF-FIELDS
EXCH_CODE
ID_BB_GLOBAL
NAME
SECURITY_TYP
TICKER
END-OF-FIELDS
TIMESTARTED=Mon Sep 21 01:01:18 BST 2015
START-OF-DATA
BBG004C5BLW2|0|5|LABUAN INTL FIN|BBG004C5BLW2|1MDB GLOBAL INVESTMENTS|EURO-DOLLAR|OGIMK|
BBG000MGZ064|0|5|HK|BBG000MGZ064|361 DEGREES INTERNATIONAL|Common Stock|1361|
BBG000QVRHX9|0|5|AV|BBG000QVRHX9|3BG EMCORE CONVRT GLB-A|Open-End Fund|EMBDGCA|
BBG000BP52R2|0|5|US|BBG000BP52R2|3M CO|Common Stock|MMM|
BBG0068TPTD9|0|5|TRACE|BBG0068TPTD9|51JOB INC|US DOMESTIC|JOBS|
BBG0069D1BR3|0|5|NOT LISTED|BBG0069D1BR3|51JOB INC|EURO-DOLLAR|JOBS|
BBG000BJD1D4|0|5|US|BBG000BJD1D4|51JOB INC-ADR|ADR|JOBS|
BBG008CTTWK1|0|5|FRANKFURT|BBG008CTTWK1|AABAR INVESTMENTS PJSC|EURO MTN|AABAR|
BBG008D4J9S9|0|5|FRANKFURT|BBG008D4J9S9|AABAR INVESTMENTS PJSC|EURO MTN|AABAR|
BBG008B2BXH2|0|5|SIX|BBG008B2BXH2|AARGAUISCHE KANTONALBANK|DOMESTIC|KBAARG|
BBG0016WJL30|0|5|LX|BBG0016WJL30|AB-AMERICAN INCOME PT-ATEURH|Open-End Fund|ABAATEH|
BBG006F3D598|0|5|BH|BBG006F3D598|ABBEY CAPITAL DAILY FUTURE-B|Fund of Funds|ABBDFUB|
END-OF-DATA
TIMEFINISHED=Mon Sep 21 01:03:22 BST 2015
END-OF-FILE
And now my questions
How can I split this file into 2 flows (field_names; data_rows)?
My problem was:
The regex component only works on row level...
The tFileInputMSDelimited does bring me nowhere...
I don't want to start parsing the file by hand (tJava)... or do I have to?
Thanks for any hints in advance,
Marco
No need to java code, check out this very simple job:
Generally, the header have fixed row count, so we need only to play with rows numbers:
tFileInputDelimited1: header 11 and limit 5
tFileInputDelimited2: header 20 and footer 3
and it works fine, if you have a dynamic rows positions, try to find these positions, save them in variables then use this job based on variables. You can also refeer to my answer here.
I'd use tJavaFlex and some Java code. If you look at the actual code its not that hard to understand how it works even if you don't really know java.
Begin:
boolean header = false;
boolean data = false;
String headerData = "";
String line;
Main:
line = input_row.line;
if(line.equalsIgnoreCase("START-OF-FIELDS") ) { header = true; }
if(line.equalsIgnoreCase("END-OF-FIELDS") ) { header = false; }
if(line.equalsIgnoreCase("START-OF-DATA") ) { data = true; }
if(line.equalsIgnoreCase("END-OF-DATA") ) { data = false; }
if(header && !line.equalsIgnoreCase("START-OF-FIELDS")) {
headerData += line + "|";
}
if (data) {
if(line.equalsIgnoreCase("START-OF-DATA")) {
output_row.line = headerData.substring(0,headerData.length()-1); //remove the trailing delimiter.
} else {
output_row.line = line;
}
} else {
continue; //lets go to the next line.
}
End:
//if you want to handle the header separately:
globalMap.put("headerData",headerData);
Hope this helps.

CRM 2011 : Plugin to create duplicate records

i created a simple plugin to create a duplicate record that refers to the parent record.
Here is my code
var pluginExecutionContext = localContext.PluginExecutionContext;
IOrganizationService service = localContext.OrganizationService;
abc= pluginExecutionContext.InputParameters["Target"] as Entity;
if (pluginExecutionContext.Depth == 1)
{
Guid abcId = abc.Id;
Entity abcCopy = new Entity("mcg_abc");
if (abc.Attributes.Contains("mcg_abccategoryoptioncode"))
{
abcCopy.Attributes["mcg_abccategoryoptioncode"] = abc.GetAttributeValue<OptionSetValue>("mcg_abccategoryoptioncode");
}
if (abc.Attributes.Contains("mcg_effectivedate"))
{
abcCopy.Attributes["mcg_effectivedate"] = isp.GetAttributeValue<DateTime>("mcg_effectivedate");
}
if (abc.Attributes.Contains("mcg_startdate"))
{
abcCopy.Attributes["mcg_startdate"] = isp.GetAttributeValue<DateTime>("mcg_startdate");
}
if (abc.Attributes.Contains("mcg_enddate"))
{
abcCopy.Attributes["mcg_enddate"] = isp.GetAttributeValue<DateTime>("mcg_enddate");
}
if (abc.Attributes.Contains("mcg_amendeddate"))
{
abcCopy.Attributes["mcg_amendeddate"] = isp.GetAttributeValue<DateTime>("mcg_amendeddate");
}
if ((abc.GetAttributeValue<OptionSetValue>("mcg_abccategoryoptioncode").Value) == 803870001)
{
//Some more fields;
}
else
{
//Some more fields;
}
// SOme more fields;
abcCopy.Attributes["mcg_parentabc"] = new EntityReference("mcg_abc", abc.Id);
service.Create(abcCopy);
}
Now the problem is all the fields before the below check are getting copied
if ((abc.GetAttributeValue<OptionSetValue>("mcg_abccategoryoptioncode").Value) == 803870001)
However fields after this check are not getting copied.
Please if anybody could suggest what mistake i have made.
In case you take field from Target - this field was updated on a client side. In case field was not updated - it would not be in Target. You should use Images to get values of unchanged fields.
The field must be empty so a exception may arise. Try to use the plugin image or change your code to this way:
if (abc.Attributes.Contains("mcg_abccategoryoptioncode")){
if ((abc.GetAttributeValue<OptionSetValue>("mcg_abccategoryoptioncode").Value) == 803870001)
....

' ', hexadecimal value 0x1F, is an invalid character. Line 1, position 1

I am trying to read a xml file from the web and parse it out using XDocument. It normally works fine but sometimes it gives me this error for day:
**' ', hexadecimal value 0x1F, is an invalid character. Line 1, position 1**
I have tried some solutions from Google but they aren't working for VS 2010 Express Windows Phone 7.
There is a solution which replace the 0x1F character to string.empty but my code return a stream which doesn't have replace method.
s = s.Replace(Convert.ToString((byte)0x1F), string.Empty);
Here is my code:
void webClient_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
using (var reader = new StreamReader(e.Result))
{
int[] counter = { 1 };
string s = reader.ReadToEnd();
Stream str = e.Result;
// s = s.Replace(Convert.ToString((byte)0x1F), string.Empty);
// byte[] str = Convert.FromBase64String(s);
// Stream memStream = new MemoryStream(str);
str.Position = 0;
XDocument xdoc = XDocument.Load(str);
var data = from query in xdoc.Descendants("user")
select new mobion
{
index = counter[0]++,
avlink = (string)query.Element("user_info").Element("avlink"),
nickname = (string)query.Element("user_info").Element("nickname"),
track = (string)query.Element("track"),
artist = (string)query.Element("artist"),
};
listBox.ItemsSource = data;
}
}
XML file:
http://music.mobion.vn/api/v1/music/userstop?devid=
0x1f is a Windows control character. It is not valid XML. Your best bet is to replace it.
Instead of using reader.ReadToEnd() (which by the way - for a large file - can use up a lot of memory.. though you can definitely use it) why not try something like:
string input;
while ((input = sr.ReadLine()) != null)
{
string = string + input.Replace((char)(0x1F), ' ');
}
you can re-convert into a stream if you'd like, to then use as you please.
byte[] byteArray = Encoding.ASCII.GetBytes( input );
MemoryStream stream = new MemoryStream( byteArray );
Or else you could keep doing readToEnd() and then clean that string of illegal characters, and convert back to a stream.
Here's a good resource for cleaning illegal characters in your xml - chances are, youll have others as well...
https://seattlesoftware.wordpress.com/tag/hexadecimal-value-0x-is-an-invalid-character/
What could be happening is that the content is compressed in which case you need to decompress it.
With HttpHandler you can do this the following way:
var client = new HttpClient(new HttpClientHandler
{
AutomaticDecompression = DecompressionMethods.GZip
| DecompressionMethods.Deflate
});
With the "old" WebClient you have to derive your own class to achieve the similar effect:
class MyWebClient : WebClient
{
protected override WebRequest GetWebRequest(Uri address)
{
HttpWebRequest request = base.GetWebRequest(address) as HttpWebRequest;
request.AutomaticDecompression = DecompressionMethods.Deflate | DecompressionMethods.GZip;
return request;
}
}
Above taken from here
To use the two you would do something like this:
HttpClient
using (var client = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }))
{
using (var stream = client.GetStreamAsync(url))
{
using (var sr = new StreamReader(stream.Result))
{
using (var reader = XmlReader.Create(sr))
{
var feed = System.ServiceModel.Syndication.SyndicationFeed.Load(reader);
foreach (var item in feed.Items)
{
Console.WriteLine(item.Title.Text);
}
}
}
}
}
WebClient
using (var stream = new MyWebClient().OpenRead("http://myrss.url"))
{
using (var sr = new StreamReader(stream))
{
using (var reader = XmlReader.Create(sr))
{
var feed = System.ServiceModel.Syndication.SyndicationFeed.Load(reader);
foreach (var item in feed.Items)
{
Console.WriteLine(item.Title.Text);
}
}
}
}
This way you also recieve the benefit of not having to .ReadToEnd() since you are working with the stream instead.
Consider using System.Web.HttpUtility.HtmlDecode if you're decoding content read from the web.
If you are having issues replacing the character
For me there were some issues if you try to replace using the string instead of the char. I suggest trying some testing values using both to see what they turn up. Also how you reference it has some effect.
var a = x.IndexOf('\u001f'); // 513
var b = x.IndexOf(Convert.ToString((byte)0x1F)); // -1
x = x.Replace(Convert.ToChar((byte)0x1F), ' '); // Works
x = x.Replace(Convert.ToString((byte)0x1F), " "); // Fails
I blagged this
I had the same issue and found that the problem was a  embedded in the xml.
The solution was:
s = s.Replace("", " ")
I'd guess it's probably an encoding issue but without seeing the XML I can't say for sure.
In terms of your plan to simply replace the character but not being able to, because you have a stream rather than a text, simply read the stream into a string and then remove the characters you don't want.
Works for me.........
string.Replace(Chr(31), "")
I used XmlSerializer to parse XML and faced the same exception.
The problem is that the XML string contains HTML codes of invalid characters
This method removes all invalid HTML codes from string (based on this thread - https://forums.asp.net/t/1483793.aspx?Need+a+method+that+removes+illegal+XML+characters+from+a+String):
public static string RemoveInvalidXmlSubstrs(string xmlStr)
{
string pattern = "&#((\\d+)|(x\\S+));";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);
if (regex.IsMatch(xmlStr))
{
xmlStr = regex.Replace(xmlStr, new MatchEvaluator(m =>
{
string s = m.Value;
string unicodeNumStr = s.Substring(2, s.Length - 3);
int unicodeNum = unicodeNumStr.StartsWith("x") ?
Convert.ToInt32(unicodeNumStr.Substring(1), 16)
: Convert.ToInt32(unicodeNumStr);
//according to https://www.w3.org/TR/xml/#charsets
if ((unicodeNum == 0x9 || unicodeNum == 0xA || unicodeNum == 0xD) ||
((unicodeNum >= 0x20) && (unicodeNum <= 0xD7FF)) ||
((unicodeNum >= 0xE000) && (unicodeNum <= 0xFFFD)) ||
((unicodeNum >= 0x10000) && (unicodeNum <= 0x10FFFF)))
{
return s;
}
else
{
return String.Empty;
}
})
);
}
return xmlStr;
}
Nobody can answer if you don't show relevant info - I mean the Xml content.
As a general advice I would put a breakpoint after ReadToEnd() call. Now you can do a couple of things:
Reveal Xml content to this forum.
Test it using VS Xml visualizer.
Copy-paste the string into a txt file and investigate it offline.

Jira: How to obtain the previous value for a custom field in a custom IssueEventListener

So how does one obtain the previous value of a custom field in a Jira IssueEventListener? I am writing a custom handler for the issueUpdated(IssueEvent) event and I would like to alter the handler's behavior if a certain custom field has changed. To detect the type of change I would like to compare the previous and current values.
(I'm am not asking about how to obtain its current value - I know how to get that from the related Issue)
I am developing against Jira 4.0.2 on Windows.
Is the best way to scan the change history for the last known value?
List changes = changeHistoryManager.getChangeHistoriesForUser(issue, user);
I'm assuming the original poster is writing a JIRA plugin with Java. I cannot be certain of how to accomplish this task in JIRA v4.0.2, but here is how I managed to do so with JIRA v5.0.2 (the solutions may very well be the same):
public void workflowEvent( IssueEvent event )
{
Long eventTypeId = event.getEventTypeId();
if( eventTypeId.equals( EventType.ISSUE_UPDATED_ID ) )
{
List<GenericValue> changeItemList = null;
try
{
changeItemList = event.getChangeLog().getRelated( "ChildChangeItem" );
}
catch( GenericEntityException e )
{
// Error or do what you need to do here.
e.printStackTrace();
}
if( changeItemList == null )
{
// Same deal here.
return;
}
Iterator<GenericValue> changeItemListIterator = changeItemList.iterator();
while( changeItemListIterator.hasNext() )
{
GenericValue changeItem = ( GenericValue )changeItemListIterator.next();
String fieldName = changeItem.get( "field" ).toString();
if( fieldName.equals( customFieldName ) ) // Name of custom field.
{
Object oldValue = changeItem.get( "oldvalue" );
Object newValue = changeItem.get( "newvalue" );
}
}
}
}
Some possible key values for changeItem are:
newvalue
oldstring
field
id
fieldtype
newstring
oldvalue
group
For many of the custom field types Object oldValue is probably just a String. But I don't think that's true for every case.
Try this example :
String codeProjetOldValue= "";
List<GenericValue> changeItemList = issueEvent.getChangeLog().getRelated("ChildChangeItem");
for (GenericValue genericValue : changeItemList) {
if(champCodeProjet.equals(genericValue.get("field"))){
codeProjetOldValue=genericValue.getString("oldstring");
break;
}
}
Note that : champCodeProjet is the name of customfield.