I have a word (docx) document stored on the OneDrive for business. It has a structure like :
<title>
Book Title
</title>
<author>
High
</author>
And then I use Microsoft.SharePoint.Client for searching title and author
var targetSite = new Uri("https://my-site.sharepoint.com");
var login = "login";
var password = "pass";
var securePassword = new SecureString();
foreach (char c in password)
{
securePassword.AppendChar(c);
}
var onlineCredentials = new SharePointOnlineCredentials(login, securePassword);
using (ClientContext clientContext = new ClientContext(targetSite))
{
clientContext.Credentials = onlineCredentials;
var query = new KeywordQuery(clientContext);
query.QueryText = "<title></title><author></author>";
var searchExecutor = new SearchExecutor(clientContext);
var result = searchExecutor.ExecuteQuery(query);
clientContext.ExecuteQuery();
}
But it does not work. it returns only word title and author. What am I doing wrong?
Syntax should follow the Keyword Query Language specification (you're using KeywordQuery)
Keyword Query Language (KQL) syntax reference
For what you ask you should use something like
query.QueryText = "Author:John AND Title:Test*";
Related
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//script").Where(x => x.InnerHtml.Contains("DealerId:")))
{
}
I am trying to get value of dealer id with the help of above code but it is not returning anything, but if you trying to find DealerId from page source of above website then it is there. please help me to achieve this or if anything wrong with above code then please correct me.
you can parse JS code with something like (https://github.com/sebastienros/jint) and extract the field you need from JS object
you can simple find this text (not elegant, but works):
UPD1: regex version
static void Main(string[] args)
{
var url = "https://www.171chryslerdodgejeepram.com/";
var web = new HtmlWeb();
var doc = web.Load(url);
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//script").Where(x => x.InnerHtml.Contains("dealerId:")))
{
var s = node.InnerText;
Regex r = new Regex(#"dealerId:\s+'(\d+)'");
Match m = r.Match(s);
Console.WriteLine(m.Groups[1].Value);
}
Console.ReadKey();
}
var url = "https://www.171chryslerdodgejeepram.com/";
var web = new HtmlWeb();
var doc = web.Load(url);
foreach (HtmlNode node in doc.DocumentNode.SelectNodes("//script").Where(x => x.InnerHtml.ToLower().Contains("dealerid")))
{
AdwordsAccount info = new AdwordsAccount();
var s = node.InnerText;
//Regex r = new Regex("dealerid(.*?)\",");
Regex r = new Regex(#"dealerId:\s+'(\d+)'");
Match m = r.Match(s.ToLower());
info.account = m.Groups[1].Value;
urlinfo.adwordsaccount.Add(info);
}
#cereberus this is my code
I need to use sharepoint client api in my project and list documents in folders that uploaded to sharepoint. My folders are under the link "https://mydomain.sharepoint.com/sites/blsmtekn/dyncrm/Shared%20Documents/Forms/AllItems.aspx"
using (ClientContext ctx = new ClientContext("https://mydomain.sharepoint.com/"))
{
string userName = "username";
string password = "password";
SecureString secureString = new SecureString();
password.ToList().ForEach(secureString.AppendChar);
ctx.Credentials = new SharePointOnlineCredentials(userName, secureString);
List list = ctx.Web.Lists.GetByTitle("/Shared Documents/");
CamlQuery caml = new CamlQuery();
caml.ViewXml = #"<View Scope='Recursive'>
<Query>
</Query>
</View>";
caml.FolderServerRelativeUrl = "/sites/blsmtekn/dyncrm/";
ListItemCollection listItems = list.GetItems(caml);
ctx.Load(listItems);
ctx.ExecuteQuery();
}
But I'm getting error like “List…does not exist at site with URL”. How can I get list of folders and files under that folders recursively.
From the top of my head I'm seeing a few mistakes: Your code states, that the name of your library is /Shared Documents/, while the name most likely is Shared Documents.
Please fix the name of your GetByTitle() call:
List list = ctx.Web.Lists.GetByTitle("Shared Documents");
The second error is, that the url to your site collection is wrong. It should be
ClientContext ctx = new ClientContext("https://mydomain.sharepoint.com/sites/blsmtekn/dyncrm/")
Additionally you can remove caml.FolderServerRelativeUrl = "/sites/blsmtekn/dyncrm/"; since that is wrong.
All in all your code should look like this:
using (ClientContext ctx = new ClientContext("https://mydomain.sharepoint.com/sites/blsmtekn/dyncrm/"))
{
string userName = "username";
string password = "password";
SecureString secureString = new SecureString();
password.ToList().ForEach(secureString.AppendChar);
ctx.Credentials = new SharePointOnlineCredentials(userName, secureString);
List list = ctx.Web.Lists.GetByTitle("Shared Documents");
CamlQuery caml = new CamlQuery();
caml.ViewXml = #"<View Scope='Recursive'>
<Query>
</Query>
</View>";
ListItemCollection listItems = list.GetItems(caml);
ctx.Load(listItems);
ctx.ExecuteQuery();
}
I am new in lucene.net , in some searches that i had , i found that i can use lucene in my project ,
now i can not fix the bugs in my code .
Let me I explain in Code
First of all i create indexes like these
var strIndexDir = path;
Directory indexDir = FSDirectory.Open(new DirectoryInfo(strIndexDir));
Analyzer std = new StandardAnalyzer(global::Lucene.Net.Util.Version.LUCENE_30)
foreach (var res in resturant)
{
var doc = new Document();
restaurantName = new Field("Name",
res.Name, Field.Store.YES,
Field.Index.ANALYZED, Field.TermVector.YES);
var restaurantId = new Field("Id",
res.RestaurantId.ToString(), Field.Store.YES,
Field.Index.NO, Field.TermVector.NO);
var restaurantSlug = new Field("Slug",
res.Slug, Field.Store.YES,
Field.Index.NO, Field.TermVector.NO);
var restaurantAddress = new Field("Address",
res.Address ?? "empty", Field.Store.YES,
Field.Index.NOT_ANALYZED, Field.TermVector.YES);
var resturantType = new Field("Type",
"restaurant", Field.Store.YES,
Field.Index.NO, Field.TermVector.NO);
doc.Add(restaurantName);
doc.Add(restaurantId);
doc.Add(restaurantSlug);
doc.Add(restaurantAddress);
doc.Add(resturantType);
idxw.AddDocument(doc);
}
idxw.Optimize();
idxw.Close();
I Think with my self the indexing is ok , becuase i want just find the restaurant name and addresses
also for search query i use this way
string strIndexDir = path;
Analyzer std = new StandardAnalyzer(Lucene.Net.Util.Version.LUCENE_30);
var indexReader = IndexReader.Open(FSDirectory.Open(path), readOnly: true);
var parserName =
new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_30, "Name", std);
var parserAddress =
new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_30, "Address", std);
var parserSlug =
new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_30, "Slug", std);
var parserTitle =
new Lucene.Net.QueryParsers.QueryParser(Lucene.Net.Util.Version.LUCENE_30, "Title", std);
var searcher = new IndexSearcher(FSDirectory.Open(path));
using (var srchr = new IndexSearcher(IndexReader.Open(directory,true)))
{
var qryName = parserName.Parse(q);
var qryAddress = parserAddress.Parse(q);
var qrySlug = parserSlug.Parse(q);
var qrytitle = parserTitle.Parse(q);
var cllctr = TopScoreDocCollector.Create(10, true);
searcher.Search(qryName, cllctr);
searcher.Search(qryAddress, cllctr);
searcher.Search(qrySlug, cllctr);
searcher.Search(qrytitle, cllctr);
var hits = cllctr.TopDocs().ScoreDocs;
Now let me say where is the problem .
for example i search this key word (q="box") want to find the restaurant name that name is boxshaharkgharb and want use "box"
the problem is that hot is always 0 but when i type boxshaharkgharb for example (q="boxshaharkgharb") the the result is ok .
how can handel that
By using wildcard * you can force Lucene to search by fragment.
If you need to do this for all queries - you need to review your choice - as Lucene best performs using whole term searches. Reason for that is that by default wildcards turn into constant score queries, while term search uses relevancy to rank results.
I'm creating a function where you can provide a content type name and target either a list or document library and create a default item. Im using the client object model for office 2013
public void MyFunction()
{
//clientContext must be authenticated already on your sharepoint site
var listName = "Default Document Set";
var docSetContentTypeName = "Document";
var newDocSetName = string.Format("Item {0}", Guid.NewGuid());
Web web = clientContext.Web;
List list = clientContext.Web.Lists.GetByTitle(listName);
clientContext.Load(clientContext.Site);
ContentTypeCollection listContentTypes = list.ContentTypes;
clientContext.Load(listContentTypes, types => types.Include
(type => type.Id, type => type.Name,
type => type.Parent));
var result = clientContext.LoadQuery(listContentTypes.Where
(c => c.Name == docSetContentTypeName));
clientContext.ExecuteQuery();
ContentType targetDocumentSetContentType = result.FirstOrDefault();
ListItemCreationInformation newItemInfo = new ListItemCreationInformation();
newItemInfo.UnderlyingObjectType = FileSystemObjectType.Folder;
newItemInfo.LeafName = newDocSetName;
ListItem newListItem = list.AddItem(newItemInfo);
newListItem["ContentTypeId"] = targetDocumentSetContentType.Id.ToString();
newListItem["Title"] = newDocSetName;
newListItem.Update();
clientContext.Load(list);
clientContext.ExecuteQuery();
}
The function works fine on ContentTypes like Item and Document Set but when I use Document, it creates an item with a content type "Document" but it has an icon of folder and acts like a folder.
Is there something I need to add?
Thanks in advance.
FileSystemObjectType.Folder is used for creating a Folder object and therefore could not be specified for creating File object. At the same time List.AddItem Method could not be used for creating a File object.
You could consider the following example that demonstrates how to create(upload) a file into Documents library:
public static void UploadFile(List list,string filePath,IDictionary<string,object> itemProperties)
{
var ctx = list.Context;
var fileInfo = new FileCreationInformation();
fileInfo.Url = Path.GetFileName(filePath);
fileInfo.Overwrite = true;
fileInfo.Content = System.IO.File.ReadAllBytes(filePath);
var file = list.RootFolder.Files.Add(fileInfo);
var listItem = file.ListItemAllFields;
foreach (var p in itemProperties)
{
listItem[p.Key] = p.Value;
}
listItem.Update();
ctx.ExecuteQuery();
}
Using Open XML SDK 2.0 for Microsoft Office you could create an empty document and upload it into Documents library:
public static void CreateAndUploadFile(List list, string filePath, IDictionary<string, object> itemProperties)
{
using (var document = WordprocessingDocument.Create(filePath, WordprocessingDocumentType.Document))
{
var mainPart = document.AddMainDocumentPart();
mainPart.Document = new Document(new Body());
}
UploadFile(list, filePath, itemProperties);
}
Usage:
var list = web.Lists.GetByTitle(listTitle);
var itemProperties = new Dictionary<string,object>();
itemProperties["Title"] = "SharePoint User Guide";
CreateAndUploadFile(list, "./SharePoint User Guide.docx", itemProperties);
what is the best way of reading xml file using linq and the below code you will see that, I have three different loops and I feel like its not elegant or do I have options to retrofit the below code?
public static void readXMLOutput(Stream stream)
{
XDocument xml = new XDocument();
xml = LoadFromStream(stream);
var header = from p in xml.Elements("App").Elements("Application")
select p;
foreach (var record in header)
{
string noym = record.Element("nomy").Value;
string Description = record.Element("Description").Value;
string Name = record.Element("Name").Value;
string Code = record.Element("Code").Value;
}
var appRoles = from q in xml.Elements("App").Elements("Application").Elements("AppRoles").Elements("Role")
select q;
foreach (var record1 in appRoles)
{
string Name = record1.Element("Name").Value;
string modifiedName = record1.Element("ModifiedName").Value;
}
var memeber = from r in xml.Elements("App").Elements("Application").Elements("AppRoles").Elements("Role").Elements("Members")
select r;
foreach (var record2 in memeber)
{
string ExpirationDate = record2.Element("ExpirationDate").Value;
string FullName = record2.Element("FullName").Value;
}
}
UPDATED:
foreach (var record in headers)
{
..............
string Name1 = record.Attribute("Name").Value;
string UnmodifiedName = record.Attribute("UnmodifiedName").Value;
string ExpirationDate = record.Attribute("ExpirationDate").Value;
string FullName = record.Attribute("FullName").Value;
...............
}
Is that your actual code ? All those string variables you are assigning in the foreach loops only have a scope of one iteration of the loop. They are created and destroyed each time.
This may not work precisely in your case depending on the xml structure. Play around with it. Try it using LinqPad
var applications = from p in xml.Descendants("Application")
select new { Nomy = p.Element("nomy").Value
, Description = p.Element("Description").Value
, Name = p.Element("Name").Value
, Code = p.Element("Code").Value
};
var appRoles = from r in xml.Descendants("Role")
select new { Name = r.Element("Name").Value
, ModifiedName = r.Element("ModifiedName").Value
};
This answer is a hierarchical query.
var headers =
from header in xml.Elements("App").Elements("Application")
select new XElement("Header",
new XAttribute("noym", header.Element("nomy").Value),
new XAttribute("Description", header.Element("Description").Value),
new XAttribute("Name", header.Element("Name").Value),
new XAttribute("Code", header.Element("Code").Value),
from role in header.Elements("AppRoles").Elements("Role")
select new XElement("Role",
new XAttribute("Name", role.Element("Name").Value),
new XAttribute("ModifiedName", role.Element("ModifiedName").Value),
from member in role.Elements("Members")
select new XElement("Member",
new XAttribute("ExpirationDate", member.Element("ExpirationDate").Value),
new XAttribute("FullName", member.Element("FullName").Value)
)
)
);