I'm trying to use Bing's REST api to geocode. But my 'y' value is always null when I check my database. Any help would be appreciated.
private void Bing(geodata address)
{
try
{
string query;
//Create a new instance for holding geocoded data
currentdata newaddress = new currentdata();
newaddress.agency = address.agency;
newaddress.calltime = address.calltime;
newaddress.city = address.city;
newaddress.state = address.state;
newaddress.incidentType = address.incidentType;
newaddress.intersection = address.intersection.Replace("&", "and");
query = newaddress.intersection.ToString() + " " + newaddress.city.ToString() + " " + newaddress.state.ToString();
// query = query.Replace("&", "and");
//Geocoder returns data in XML format so we need to
//create a new instance of XMLTextReader and provide an url
XmlTextReader reader = new XmlTextReader
("http://dev.virtualearth.net/REST/v1/Locations/" + query + "?o=xml&key=MYBINGKEY");
//Specify the way how white space is handled
reader.WhitespaceHandling = WhitespaceHandling.Significant;
//Start reading geocoded data
while (reader.Read())
{
string node = reader.Name.ToString(); //current node in XML document
string value = reader.ReadString(); //value/inner text of current XML node
switch (node)
{
case "Name":
newaddress.intersection = value;
break;
case "Latitude":
newaddress.y = double.Parse(value);
break;
case "Longitude":
newaddress.x = double.Parse(value);
break;
default:
continue;
}
}
//Add geocoded address to our table
cD.currentdatas.InsertOnSubmit(newaddress);
cD.SubmitChanges();
}
catch
{
}
}
Does your location info contains a period (.), a comma (,), a colon (:) or a plus sign (+)? You should use the Unstructured URL syntax if this is the case. Info here:
Related
I am trying to retrieve all elements from an XML file, but I just can reach one, is there any way I can retrieve all?
HttpWebResponse objResponse = (HttpWebResponse)objRequest.GetResponse();
using (XmlReader reader = XmlReader.Create(new StreamReader(objResponse.GetResponseStream())))
{
while (reader.Read())
{
#region Get Credit Score
//if (reader.ReadToDescendant("results"))
if (reader.ReadToDescendant("ssnMatchIndicator"))
{
string ssnMatchIndicator = reader.Value;
}
if (reader.ReadToDescendant("fileHitIndicator"))
{
reader.Read();//this moves reader to next node which is text
result = reader.Value; //this might give value than
Res.Response = true;
Res.SocialSecurityScore = result.ToString();
//break;
}
else
{
Res.Response = false;
Res.SocialSecurityScore = "Your credit score might not be available. Please contact support";
}
#endregion
#region Get fileHitIndicator
if (reader.ReadToDescendant("fileHitIndicator"))
{
reader.Read();
Res.fileHitIndicator = reader.Value;
//break;
}
#endregion
}
}
Can somebody help me out with this issue?
I am also using objResponse.GetResponseStream() because the XML comes from a response from server.
Thanks a lot in advance.
Try this :
XmlDataDocument xmldoc = new XmlDataDocument();
XmlNodeList xmlnode ;
int i = 0;
string str = null;
FileStream fs = new FileStream("product.xml", FileMode.Open, FileAccess.Read);
xmldoc.Load(fs);
xmlnode = xmldoc.GetElementsByTagName("Product");
for (i = 0; i <= xmlnode.Count - 1; i++)
{
xmlnode[i].ChildNodes.Item(0).InnerText.Trim();
str = xmlnode[i].ChildNodes.Item(0).InnerText.Trim() + " " + xmlnode[i].ChildNodes.Item(1).InnerText.Trim() + " " + xmlnode[i].ChildNodes.Item(2).InnerText.Trim();
MessageBox.Show (str);
}
I don't know why what you're doing is not working, but I wouldn't use that method. I've found the following to work well. Whether you're getting the xml from a stream, just put it into a string and bang...
StreamReader reader = new StreamReader(sourcepath);
string xml = reader.ReadToEnd();
reader.Close();
XmlDocument doc = new XmlDocument();
doc.LoadXml(xml);
XmlNodeList list = doc.GetElementsByTagName("*");
foreach (XmlNode nd in list)
{
switch (nd.Name)
{
case "ContactID":
var ContactIdent = nd.InnerText;
break;
case "ContactName":
var ContactName = nd.InnerText;
break;
}
}
To capture what is between the Xml tags, if there are no child Xml tags, use the InnerText property, e.g. XmlNode.InnerText. To capture what is between the quotes in the nodes' attributes, use XmlAttribute.Value.
As for iterating through the attributes, if one of your nodes has attributes, such as the elements "Name", "SpectralType" and "Orbit" in the Xml here:
<System>
<Star Name="Epsilon Eridani" SpectralType="K2v">
<Planets>
<Planet Orbit="1">Bill</Planet>
<Planet Orbit="2">Moira</Planet>
</Planets>
</Star>
</System>
Detect them using the Attributes property, and iterate through them as shown:
if (nd.Attributes.Count > 0)
{
XmlAttributeCollection coll = nd.Attributes;
foreach (XmlAttribute cn in coll)
{
switch (cn.Name)
{
case "Name":
thisStar.Name = cn.Value;
break;
case "SpectralType":
thisStar.SpectralClass = cn.Value;
break;
}
}
}
You might find some more useful information HERE.
Below is a sample of the type of XML file I am trying to handle. If I have only one part along with an accompanying number/character I can process the data extraction without the necessity of the 'if (!reader.EOF)' control structure. However when I try to include this structure so that I can loop back to checking for another part, number, and character group, it deadlocks.
Any advice as to how to do this properly? This was the most efficient idea that popped into my head. I am new to reading data from XMLs.
Sample Xml:
<?xml version="1.0" encoding="UTF-8"?>
<note>
<part>100B</part>
<number>45</number>
<character>a</character>
<part>100C</part>
<number>55</number>
<character>b</character>
</note>
Code:
String part = "part";
String number = "number";
String character = "character";
String appendString = "";
StringBuilder sb = new StringBuilder();
try
{
XmlTextReader reader = new XmlTextReader("myPath");
while (reader.Read())
{
switch (reader.NodeType)
{
case XmlNodeType.Element: // The node is an element.
myLabel:
if (reader.Name == part)
{
part = reader.ReadInnerXml();
}
if (reader.Name == number)
{
number = reader.ReadInnerXml();
number = double.Parse(number).ToString("F2"); //format num
}
if (reader.Name == character)
{
character = reader.ReadInnerXml();
}
//new string
appendString = ("Part: " + part + "\nNumber: " + number +
"\nCharacter: " + character + "\n");
//concatenate
sb.AppendLine(appendString);
if (reader.EOF != true)
{
Debug.Log("!eof");
part = "part";
number = "number";
character = "character";
goto myLabel;
}
//print fully concatenated result
sb.ToString();
//reset string builder
sb.Length = 0;
break;
}
}
}
catch (XmlException e)
{
// Write error.
Debug.Log(e.Message);
}
catch (FileNotFoundException e)
{
// Write error.
Debug.Log(e);
}
catch(ArgumentException e)
{
// Write error.
Debug.Log(e);
}
XmlReader class has many useful methods. Use it.
See this:
var sb = new StringBuilder();
using (var reader = XmlReader.Create("test.xml"))
{
while (reader.ReadToFollowing("part"))
{
var part = reader.ReadElementContentAsString();
sb.Append("Part: ").AppendLine(part);
reader.ReadToFollowing("number");
var number = reader.ReadElementContentAsDouble();
sb.Append("Number: ").Append(number).AppendLine();
reader.ReadToFollowing("character");
var character = reader.ReadElementContentAsString();
sb.Append("Character: ").AppendLine(character);
}
}
Console.WriteLine(sb);
Alexander's answer is fine, I just want to add sample using XDocument, according comments of Jon Skeet:
var sb = new StringBuilder();
var note = XDocument.Load("test.xml").Root.Descendants();
foreach (var el in note)
{
sb.Append(el.Name).Append(": ").AppendLine(el.Value);
}
Console.WriteLine(sb);
I have approximately 10 MERGEFIELD in a document that I'm trying to replace the Text with some value. Here's the code.
using (WordprocessingDocument document = WordprocessingDocument.Open(destinationFileName, true))
{
document.ChangeDocumentType(DocumentFormat.OpenXml.WordprocessingDocumentType.Document);
MainDocumentPart docPart = document.MainDocumentPart;
docPart.AddExternalRelationship("http://schemas.openxmlformats.org/officeDocument/2006/relationships/attachedTemplate", new Uri(destinationFileName, UriKind.RelativeOrAbsolute));
docPart.Document.Save();
IEnumerable<FieldChar> fldChars = document.MainDocumentPart.RootElement.Descendants<FieldChar>();
if (fldChars == null) { return; }
string fieldList = string.Empty;
FieldChar fldCharStart = null;
FieldChar fldCharEnd = null;
FieldChar fldCharSep = null;
FieldCode fldCode = null;
string fldContent = String.Empty;
int i = 1;
foreach(var fldChar in fldChars)
{
System.Diagnostics.Debug.WriteLine(i + ": " + fldChar);
i++;
string fldCharPart = fldChar.FieldCharType.ToString();
System.Diagnostics.Debug.WriteLine("Field Char Length: " + fldChar.Count());
System.Diagnostics.Debug.WriteLine("Field Char part: " + fldCharPart);
switch(fldCharPart)
{
case "begin": // start of the field
fldCharStart = fldChar;
System.Diagnostics.Debug.WriteLine("Field Char Start: " + fldCharStart);
// get the field code, which will be an instrText element
// either as sibling or as a child of the parent sibling
fldCode = fldCharStart.Parent.Descendants<FieldCode>().FirstOrDefault();
System.Diagnostics.Debug.WriteLine("Field Code: " + fldCode);
if (fldCode == null)
{
fldCode = fldCharStart.Parent.NextSibling<Run>().Descendants<FieldCode>().FirstOrDefault();
System.Diagnostics.Debug.WriteLine("New Field Code: " + fldCode);
}
if (fldCode != null && fldCode.InnerText.Contains("MERGEFIELD"))
{
fldContent = getFieldValue(query, prescriber, fldCode.InnerText);
fieldList += fldContent + "\n";
System.Diagnostics.Debug.WriteLine("Field content: " + fldContent);
}
break;
case "end": // end of the field
fldCharEnd = fldChar;
System.Diagnostics.Debug.WriteLine("Field char end: " + fldCharEnd);
break;
case "separate": // complex field with text result
fldCharSep = fldChar;
break;
default:
break;
}
if((fldCharStart != null) && (fldCharEnd != null))
{
if(fldCharSep != null)
{
Text elemText = (Text)fldCharSep.Parent.NextSibling().Descendants<Text>().FirstOrDefault();
elemText.Text = fldContent;
System.Diagnostics.Debug.WriteLine("Element text: " + elemText);
// Delete all field chas with their runs
DeleteFieldChar(fldCharStart);
DeleteFieldChar(fldCharEnd);
DeleteFieldChar(fldCharSep);
fldCode.Remove();
}
else
{
Text elemText = new Text(fldContent);
fldCode.Parent.Append(elemText);
fldCode.Remove();
System.Diagnostics.Debug.WriteLine("Element Text !sep: " + elemText);
DeleteFieldChar(fldCharStart);
DeleteFieldChar(fldCharEnd);
DeleteFieldChar(fldCharSep);
}
fldCharStart = null;
fldCharEnd = null;
fldCharSep = null;
fldCode = null;
fldContent = string.Empty;
}
}
System.Diagnostics.Debug.WriteLine("Field list: " + fieldList);
}
It works to some extent. The problem is when there are more than one field in a paragraph. I have about 4 merge fields in one paragraph in this document, and one field in each paragraph after that. Only the first merge field in the paragraph is being updated and the rest fields in the paragraphs is untouched. Then, it moves to the next paragraph and looks for the field. How can I fix this?
Looks like you are over complicating a simple Mailmerge replacement. Instead of looping through paragraphs you could rather get all mailmerge fields within a document and replace them.
private const string FieldDelimeter = " MERGEFIELD ";
foreach (FieldCode field in doc.MainDocumentPart.RootElement.Descendants<FieldCode>())
{
var fieldNameStart = field.Text.LastIndexOf(FieldDelimeter, System.StringComparison.Ordinal);
var fieldName = field.Text.Substring(fieldNameStart + FieldDelimeter.Length).Trim();
foreach (Run run in doc.MainDocumentPart.Document.Descendants<Run>())
{
foreach (Text txtFromRun in run.Descendants<Text>().Where(a => a.Text == "«" + fieldName + "»"))
{
txtFromRun.Text = "Replace what the merge field here";
}
}
}
doc.MainDocumentPart.Document.Save();
doc is of type WordprocessingDocument.
This will replace all merge fields regardless of the amount of fields in a paragraph.
So I have a long string containing pointy brackets that I wish to extract text parts from.
string exampleString = "<1>text1</1><27>text27</27><3>text3</3>";
I want to be able to get this
1 = "text1"
27 = "text27"
3 = "text3"
How would I obtain this easily? I haven't been able to come up with a non-hacky way to do it.
Thanks.
Using basic XmlReader and some other tricks to do wrapper to create XML-like data, I would do something like this
string xmlString = "<1>text1</1><27>text27</27><3>text3</3>";
xmlString = "<Root>" + xmlString.Replace("<", "<o").Replace("<o/", "</o") + "</Root>";
string key = "";
List<KeyValuePair<string,string>> kvpList = new List<KeyValuePair<string,string>>(); //assuming the result is in the KVP format
using (XmlReader xmlReader = XmlReader.Create(new StringReader(xmlString))){
bool firstElement = true;
while (xmlReader.Read()) {
if (firstElement) { //throwing away root
firstElement = false;
continue;
}
if (xmlReader.NodeType == XmlNodeType.Element) {
key = xmlReader.Name.Substring(1); //cut of "o"
} else if (xmlReader.NodeType == XmlNodeType.Text) {
kvpList.Add(new KeyValuePair<string,string>(key, xmlReader.Value));
}
}
}
Edit:
The main trick is this line:
xmlString = "<Root>" + xmlString.Replace("<", "<o").Replace("<o/", "</o") + "</Root>"; //wrap to make this having single root, o is put to force the tagName started with known letter (comment edit suggested by Mr. chwarr)
Where you first replace all opening pointy brackets with itself + char, i.e.
<1>text1</1> -> <o1>text1<o/1> //first replacement, fix the number issue
and then reverse the sequence of all the opening point brackets + char + forward slash to opening point brackets + forward slash + char
<o1>text1<o/1> -> <o1>text1</o1> //second replacement, fix the ending tag issue
Using simple WinForm with RichTextBox to print out the result,
for (int i = 0; i < kvpList.Count; ++i) {
richTextBox1.AppendText(kvpList[i].Key + " = " + kvpList[i].Value + "\n");
}
Here is the result I get:
This is far from bulletproof, but you could use a combination of split and Regex matching:
string exampleString = "<1>text1</1><27>text27</27><3>text3</3>";
string[] results = exampleString.Split(new string[] { "><" }, StringSplitOptions.None);
Regex r = new Regex(#"^<?(\d+)>([^<]+)<");
foreach (string result in results)
{
Match m = r.Match(result);
if (m.Success)
{
string index = m.Groups[1].Value;
string value = m.Groups[2].Value;
}
}
The most non-bulletproof example I can think of is if your text contains a "<", that would pretty much break this.
I am currently using lucene.net to search the content of files for keyword search. I am able to get the results correctly but I have a scenario where I need to display the keywords found in a particular file.
There are two different files containing "karthik" and "steven", and if I search for "karthik and steven" I am able to get both the files displayed. If I search only for "karthik" and "steven" separately, only the respective files are getting displayed.
When I search for "karthik and steven" simultaneously I get both the files in the result as I am displaying the filename alone, and now I need to display the particular keyword found in that particular file as a record in the listview.
Public bool StartSearch()
{
bool bResult = false;
Searcher objSearcher = new IndexSearcher(mstrIndexLocation);
Analyzer objAnalyzer = new StandardAnalyzer();
try
{
//Perform Search
DateTime dteStart = DateTime.Now;
Query objQuery = QueryParser.Parse(mstrSearchFor, "contents", objAnalyzer);
Hits objHits = objSearcher.Search(objQuery, objFilter);
DateTime dteEnd = DateTime.Now;
mlngTotalTime = (Date.GetTime(dteEnd) - Date.GetTime(dteStart));
mlngNumHitsFound = objHits.Length();
//GeneratePreviewText(objQuery, mstrSearchFor,objHits);
//Generate results - convert to XML
mstrResultsXML = "";
if (mlngNumHitsFound > 0)
{
mstrResultsXML = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?><Results>";
//Loop through results
for (int i = 0; i < objHits.Length(); i++)
{
try
{
//Get the next result
Document objDocument = objHits.Doc(i);
//Extract the data
string strPath = objDocument.Get("path");
string strFileName = objDocument.Get("name");
if (strPath == null) { strPath = ""; }
string strLastWrite = objDocument.Get("last_write_time");
if (strLastWrite == null)
strLastWrite = "unavailable";
else
{
strLastWrite = DateField.StringToDate(strLastWrite).ToShortDateString();
}
double dblScore = objHits.Score(i) * 100;
string strScore = String.Format("{0:00.00}", dblScore);
//Add results as an XML row
mstrResultsXML += "<Row>";
//mstrResultsXML += "<Sequence>" + (i + 1).ToString() + "</Sequence>";
mstrResultsXML += "<Path>" + strPath + "</Path>";
mstrResultsXML += "<FileName>" + strFileName + "</FileName>";
//mstrResultsXML += "<Score>" + strScore + "%" + "</Score>";
mstrResultsXML += "</Row>";
}
catch
{
break;
}
}
//Finish off XML
mstrResultsXML += "</Results>";
//Build Dataview (to bind to datagrid
DataSet objDS = new DataSet();
StringReader objSR = new StringReader(mstrResultsXML);
objDS.ReadXml(objSR);
objSR = null;
mobjResultsDataView = new DataView();
mobjResultsDataView = objDS.Tables[0].DefaultView;
}
//Finish up
objSearcher.Close();
bResult = true;
}
catch (Exception e)
{
mstrError = "Exception: " + e.Message;
}
finally
{
objSearcher = null;
objAnalyzer = null;
}
return bResult;
}
Above is the code i am using for search and the xml i am binding to the listview, now i need to tag the particular keywords found in the respective document and display it in the listview as recordsss,simlar to the below listview
No FileName KeyWord(s)Found
1 Test.Doc karthik
2 Test2.Doc steven
i hope u guys undesrtood the question,
This depends on how your documents were indexed. You'll need to extract the original content, pass it through the analyzer to get the indexed tokens, and check which matches the generated query.
Just go with the Highlighter.Net package, part of contrib, which does this and more.