I'm completely stuck in retrieving a specific node from a responseXML object that I got back from the GetUserProfileByName (SharePoint / SPServices). I need a specific PropertyData node (in the example "FirstName") and then retrieve the value of the "FirstName". Retrieving the value is not a problem, retrieving the specific node is...
Below a part from the returned XML (for the sake of the example I stripped some properties):
...
<PropertyData>
<Name>UserProfile_GUID</Name>
<Values>
<ValueData>
<Value xmlns:q1="...">206b47c7-cfdc-...</Value>
</ValueData>
</Values>
</PropertyData>
<PropertyData>
<Name>FirstName</Name>
<Values>
<ValueData>
<Value xsi:type="xsd:string">Maarten</Value>
</ValueData>
</Values>
</PropertyData>
...
Since I know that I need the property FirstName, I do not want to iterate through the entire set of PropertyData nodes until I've the correct one (slow). In XPath I can select FirstName just by saying:
//PropertyData[Name='FirstName']/Values/ValueData/Value
However, I cannot do that in the xData.responseXML object. I tried the following filter, finds and other things (in all kinds of variations):
$(xData.responseXML).SPFilterNode("PropertyData").find("[Name*=FirstName]")
$(xData.responseXML).SPFilterNode("PropertyData").find("[Name*='FirstName']")
$(xData.responseXML).SPFilterNode("PropertyData").filter("[Name*=FirstName]")
$(xData.responseXML).SPFilterNode("PropertyData[Name='FirstName']")
I did many searches, but was not able to find an answer. There were many partial answer which a I all tried, but were not working. Any one a clue...
Thanks in advance!
Maarten
#Maarten
I'm not at my computer right now to test, but try this:
$(xData.responseXML).find("Name:contains('FirstName')").closest("PropertyData")
REVISION 1:
Given your feedback that an additional element is returned (the phonetic field), here is a revised selector to only return the one containing the FirstName element:
$(xData.responseXML)
.find("Name:contains('FirstName')")
.not(":contains('SPS-PhoneticFirstName')")
.closest("PropertyData");
Paul
Related
I'm setting up a faceted search in MarkLogic. I have the following range indexes configured:
That is, I have two indexes. The first is on namespace http://www.corbas.co.uk/ns/presentations and local name keyword. The second has the local name level. The collation URI for both is http://marklogic.com/collation/en/S1.
When I try to search using the following I see errors related to collations:
xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search"
at "/MarkLogic/appservices/search/search.xqy";
search:search("levels:Intermediate",
<options xmlns="http://marklogic.com/appservices/search">
<return-results>true</return-results>
<return-facets>true</return-facets>
<constraint name="keywords" facet="true">
<range type="xs:string" collation="http://marklogic.com/collation/en/S1">
<element ns="http://www.corbas.co.uk/ns/presentations" name="keyword"/>
</range>
</constraint>
<constraint name="levels" facet="true">
<range type="xs:string" collation="http://marklogic.com/collation/en/S1">
<element ns="http://www.corbas.co.uk/ns/presentations" name="level"/>
</range>
</constraint>
</options>)
I get the following error:
XDMP-ELEMRIDXNOTFOUND: cts:search(fn:collection(),
cts:element-range query(fn:QName("http://www.corbas.co.uk/ns/presentations","level"),
"=", "Intermediate", ("collation=http://marklogic.com/collation/en/S1"), 1),
("score-logtfidf", "faceted", cts:score-order("descending")),
xs:double("1"), ()) -- No string element range index for
{http://www.corbas.co.uk/ns/presentations}level
collation=http://marklogic.com/collation/en/S1
What am I doing wrong?
Strange Message. If it even got that far, then it looks like your database default collation is changed. Does not answer the question. just strange.
Forst off, I would always add the collation to the constraint:
<search:range type="xs:string" facet="true"
collation="http://marklogic.com/collation/en/S1">
Second, I always troubleshoot range index issue from the query console:
use cts:values() to verify that your indexes are in place and in the namespace and collation you expect. This removes other layers and verifies that the index is as you expect.
And another item: MarkLogic range indexes do not exist until content is indexed. Are you sure you have not turned off auto-index on the database and perhaps content is not indexed? That would give you an error.
To be honest, I would have expected a different error message. I would have expected MarkLogic to complain it couldn't find an index for root collation, because you have not added collation attributes on the range elements in the search options.
Maybe adding those will help.
HTH!
It looks to me like your configuration is correct, which suggests to me that the problem is timing. Once you specify what indexes you want, MarkLogic gets to work creating them. If you run a query that requires those indexes before MarkLogic finishes creating them, you get this error. Depending on the amount of content you have, the creation process can be very quick or take hours.
To check the status, point your browser to the Admin UI (http://localhost:8001) and navigate to the configuration page for your database. Click on the Status tab and look for "Reindexing/Refragmenting State"—if MarkLogic is still reindexing, it will tell you so here and you'll get updates on its progress. (You can also get this information through the Management API.)
I need to create a query where the params are like:
queryParams.put("path", "/content/myFolder");
queryParams.put("1_property", "myProperty");
queryParams.put("1_property.operation", "exists");
queryParams.put("p.limit", "-1");
But, I need to exclude a certain path inside this blanket folder , say: "/content/myFolder/wrongFolder" and search in all other folders (whose number keeps on varying)
Is there a way to do so ? I didn't find it exactly online.
I also tried the unequals operation as the parent path is being saved in a JCR property, but still no luck. I actually need unlike to avoid all occurrences of the path. But there is no such thing:
path=/main/path/to/search/in
group.1_property=cq:parentPath
group.1_property.operation=unequals
group.1_property.value=/path/to/be/avoided
group.2_property=myProperty
group.2_property.operation=exists
group.p.or=true
p.limit=-1
This is an old question but the reason you got more results later lies in the way in which you have constructed your query. The correct way to write a query like this would be something like:
path=/main/path/where
property=myProperty
property.operation=exists
property.value=true
group.p.or=true
group.p.not=true
group.1_path=/main/path/where/first/you/donot/want/to/search
group.2_path=/main/path/where/second/you/donot/want/to/search
p.limit=-1
A couple of notes: your group.p.or in your last comment would have applied to all of your groups because they weren't delineated by a group number. If you want an OR to be applied to a specific group (but not all groups), you would use:
path=/main/path/where
group.1_property=myProperty
group.1_property.operation=exists
group.1_property.value=true
2_group.p.or=true
2_group.p.not=true
2_group.3_path=/main/path/where/first/you/donot/want/to/search
2_group.4_path=/main/path/where/second/you/donot/want/to/search
Also, the numbers themselves don't matter - they don't have to be sequential, as long as property predicate numbers aren't reused, which will cause an exception to be thrown when the QB tries to parse it. But for readability and general convention, they're usually presented that way.
I presume that your example was just thrown together for this question, but obviously your "do not search" paths would have to be children of the main path you want to search or including them in the query would be superfluous, the query would not be searching them anyway otherwise.
AEM Query Builder Documentation for 6.3
Hope this helps someone in the future.
Using QueryBuilder you can execute:
map.put("group.p.not",true)
map.put("group.1_path","/first/path/where/you/donot/want/to/search")
map.put("group.2_path","/second/path/where/you/donot/want/to/search")
Also I've checked PredicateGroup's class API and they provide a setNegated method. I've never used it myself, but I think you can negate a group and combine it into a common predicate with the path you are searching on like:
final PredicateGroup doNotSearchGroup = new PredicateGroup();
doNotSearchGroup.setNegated(true);
doNotSearchGroup.add(new Predicate("path").set("path", "/path/where/you/donot/want/to/search"));
final PredicateGroup combinedPredicate = new PredicateGroup();
combinedPredicate.add(new Predicate("path").set("path", "/path/where/you/want/to/search"));
combinedPredicate.add(doNotSearchGroup);
final Query query = queryBuilder.createQuery(combinedPredicate);
Here is the query to specify operator on given specific group id.
path=/content/course/
type=cq:Page
p.limit=-1
1_property=jcr:content/event
group.1_group.1_group.daterange.lowerBound=2019-12-26T13:39:19.358Z
group.1_group.1_group.daterange.property=jcr:content/xyz
group.1_group.2_group.daterange.upperBound=2019-12-26T13:39:19.358Z
group.1_group.2_group.daterange.property=jcr:content/abc
group.1_group.3_group.relativedaterange.property=jcr:content/courseStartDate
group.1_group.3_group.relativedaterange.lowerBound=0
group.1_group.2_group.p.not=true
group.1_group.1_group.p.not=true
when i list the inventory, the default setting filters the Status field with "!=OBSOLETE".
Can I put in a command that will not list any items with status of obsolete or pendobs.
or filter the list on 2 different status'
You can filter the list to two different statuses. For that you put something like (without the quotes) "=status1, =status2".
That same trick never worked for me to filter out more than one status. "!=status1, !=status2", for example, would not work.
Saved and default queries can help take care of that if you wish.
If you have access to the Where Clause, you could edit there query to state something like this:
status not in ('obsolete', 'pendobs')
This is the best way I've found to do an exclusive query as opposed to the standard inclusive query.
Out of the box, you can add PENDOBS to the filter so you exclude OBSOLETE and PENDOBS. If you want the behavior of the application to change, you have to edit the Java .class file in this case. Some modules allow you to edit this from Application Designer, but it is strange that Inventory module, requires editing the .class file.
c:\IBM\SMP\maximo\applications\maximo\maximouiweb\webmodule\WEB-INF\classes\psdi\webclient\beans\item\ItemAppBean.class
Below is the relevant Java code. You'd have to edit the Java file and rebuild your maximo.ear for the List view to exclude PENDOBS from the list view.
public void initializeApp()
throws MXException, RemoteException
{
DataBean resultsBean = app.getResultsBean();
Translate translate = MXServer.getMXServer().getMaximoDD().getTranslator();
String status = (new StringBuilder()).append("!=").append(translate.toExternalDefaultValue("ITEMSTATUS", "OBSOLETE", null, null)).toString();
resultsBean.setQbe("status", status);
resultsBean.reset();
super.initializeApp();
}
Quick background - I have a form that offers a handful of optional options to users and a search method on my service that accepts all those fields and attaches the necessary Where() conditions on the master IQueryable list.
One of those filters is a list of strings that must be compared to a combination of three different fields in the IQueryable. here's the code throwing the "could not resolve property" error:
var searchResults = _transactionHeaders.Retrieve();
if (subgroups.Any())
searchResults = searchResults.Where(s => subgroups.Contains(s.CustomerType + s.RusNumber + s.GroupNumber));
return searchResults.ToList()
I've read a few posts that suggest an alias needs to be created for any properties not directly mapped in the NHibernate mapping. I'm not quite sure that is the solution to my problem.
Suggestions? Thanks for any help you can offer.
Linq2Nhibernate can't understand a .Contains method call to. You'll have to change your query so it's compatible with linq2nhibernate.
WSS 3.0 List Service
I am running GetListItems() on a Picture Library (name Pictures) using the follow CAML query:
<Query>
</Query>
<ViewFields>
<FieldRef Name="EncodedAbsUrl"/>
<FieldRef Name="Title"/>
<FieldRef Name="ContentType"/>
</ViewFields>
<QueryOptions>
<Folder>Pictures\Uploads</Folder>
<ViewAttributes Scope="RecursiveAll"/>
</QueryOptions>
This query correctly returns all files and folders in the Uploads folder.
However, if I navigate to the Uploads folder and select Edit Permissions on the Uploads folder then select Actions > Edit Permissions and then click OK on the confirmation box this query no longer works.
I do not believe this is related to permissions, because I did not modify the permissions at all I just “cop[ied] permissions from parent, and then stop[ped] inheriting permissions,” by selecting Edit Permissions. In addition, I do not receive an error message when running this query, I just get an empty result set.
Other things I have tried:
Removing all tags in QueryOptions: This still does not return the Uploads folder or any file or folder under it
Adding permissions directly to the folder for my user account: This does not help
Searching for something with a similar problem or some sort of solution: No avail
Other information:
Calling this from C# Win Form App
Does anyone know how to fix or work around this? If more detail or clarification is necessary please let me know.
So after some more experimenting, a solution was found, though not well explained or documented. The problem was related to how the GetListItems function was being called, here is the code that was not working correctly:
System.Xml.XmlNode ndListView = listProxy.GetListAndView("Pictures", "");
string strListID = ndListView.ChildNodes[0].Attributes["Name"].Value;
XmlNode returnNode = listProxy.GetListItems(strListID, strViewID, queryNode, viewNode, _maxFolders, optionNode, null);
This was not working as expected for the situation explained above, however, it was working for every other folder and file. The solution was to send GetListItems the list name, "Pictures" instead of the list GUID, like so:
XmlNode returnNode = listProxy.GetListItems("Pictures", strViewID, queryNode, viewNode, _maxFolders, optionNode, null);
Update
Furthermore, MSDN documentation recommends the usage of GUID instead of the list name when using the Lists.GetListItem method:
listName: A string that contains either
the display name or the GUID for the
list. It is recommended that you use
the GUID, which must be surrounded by
curly braces ({}). When querying the
UserInfo table, the string contains
"UserInfo".
I do not know why this code works and the original does not. Although my problem has been solved, does anyone have a clue why my original code does not work (only for the situation explained above) and the modified code work?
So after some more experimenting, a solution was found, though not well explained or documented. The problem was related to how the GetListItems function was being called, here is the code that was not working correctly:
System.Xml.XmlNode ndListView = listProxy.GetListAndView("Pictures", "");
string strListID = ndListView.ChildNodes[0].Attributes["Name"].Value;
XmlNode returnNode = listProxy.GetListItems(strListID, strViewID, queryNode, viewNode, _maxFolders, optionNode, null);
This was not working as expected for the situation explained above, however, it was working for every other folder and file. The solution was to send GetListItems the list name, "Pictures" instead of the list GUID, like so:
XmlNode returnNode = listProxy.GetListItems("Pictures", strViewID, queryNode, viewNode, _maxFolders, optionNode, null);