How to keep cts:highlight from matching inside XML tags? - api

I am trying to search some content and highlight the search strings present in the XML content(like google) in MarkLogic using REST API. The problem is when I am including "ME" in the search-string,it's highlighting the 'i' tags(html Italic tags) along with the "Me" in the content. I have created a document with some elements and running a word-query on the document.
For example XML content:
<resources>
<title> some data from me</title>
<desc> more data <i> from </i> somewhere by me </desc>
</resources>
I have created a document with root node 'resources' and child elements 'title' and 'desc' and searching the search strings within the document using word-query.
Now when i search for "some me" ,its retrieving the content like
<resources>
<title> <<span class="highlight">some</span> data from <<span class="highlight">me</span>
</title>
<desc> more data <<span class="highlight">i</span>> from <<span class="highlight">i</span>> somewhere by <span class="highlight">me</span> </desc>
</resources>
Url:
localhost:9000/v1/search?q=some me&collection=Data&start=0&pageLength=10&options=Transformation&format=json
I am using cts:highlight for highlighting,some thing like :
cts:highlight($final-result, $query, fn:concat('<span class="highlight">',$cts:text,'</span>')), $custom-config)
Any ideas on why the html elements are highlighted here?
Thanks in Advance.

You probably inserted your document in text format, not xml format. I can reproduce your issue by inserting in text format:
xdmp:document-insert("test.xml", text {"<resources>
<title> some data from me</title>
<desc> more data <i> from </i> somewhere by me </desc>
</resources>"})
then running a cts:highlight on that document:
cts:highlight(doc("test.xml"), cts:parse("some me"), concat('<span class="highlight">', $cts:text, '</span>'))
But if I re-insert the document as XML:
xdmp:document-insert("test.xml", <resources>
<title> some data from me</title>
<desc> more data <i> from </i> somewhere by me </desc>
</resources>)
then the same cts:highlight works better:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<title> <span class="highlight">some</span> data from <span class="highlight">me</span></title>
<desc> more data <i> from </i> somewhere by <span class="highlight">me</span> </desc>
</resources>
If I add the suggestion from #ehennum and #mholstege and instead run this cts:highlight:
cts:highlight(doc("test.xml"), cts:parse("some me"), <span class="highlight">{$cts:text}</span>)
then I get what I would guess you're looking for:
<?xml version="1.0" encoding="UTF-8"?>
<resources>
<title> <span class="highlight">some</span> data from <span class="highlight">me</span></title>
<desc> more data <i> from </i> somewhere by <span class="highlight">me</span> </desc>
</resources>

What version of MarkLogic is this?
Can you include a more complete example? What is $custom-config for example? And how is the REST call results linked to cts:highlight? For markup to be highlighted in this way, that results would have to be text rather than XML.
By the way, the third argument to cts:highlight is an expression -- if you want to create markup, just use constructors there, not string concatenation:
cts:highlight($final-result, $query, <span class="highlight">{$cts:text}</span>, $custom-config)

Try supplying the tags in the cts:hightlight() expression as nodes instead of a string.
That is, instead of
fn:concat('<span class="highlight">',$cts:text,'</span>')
try
<span class="highlight">{$cts:text}</span>
For more information, see the first example in:
http://docs.marklogic.com/cts:highlight?q=cts:highlight
Hoping that helps,

Related

How can I use pagemap with google custom search refinements?

I'm trying to add refinements to my google custom search.
I have meta tags on just about every page of the site, such as
<meta name="type-id" content="241" />
Where there are many different types, and I want to have one refinement for each type.
In the docs, it says
You can also use these more:pagemap: operators with refinement labels
But I have been unable to do that.
Note that I have had success using more:pagemap:metatags-type-id:241 in the search input, or as a webSearchQueryAddition - but despite googles docs, I haven't been able to get it to work with a refinement.
Here's a sample from my cse.xml (removing some attributes from the CustomSearchEngine tag):
<?xml version="1.0" encoding="UTF-8"?>
<CustomSearchEngine>
<Title>Test</Title>
<Context>
<Facet>
<FacetItem>
<Label name="videos" mode="FILTER">
<Rewrite>more:p:metatags-article-keyword:121</Rewrite>
</Label>
<Title>Videos</Title>
</FacetItem>
</Facet>
</Context>
</CustomSearchEngine>
Is this supposed to work? Am I using wrong syntax in the rewrite rule? Has anyone else done something like this?
Your label in the facet should be mode="BOOST" if you want to restrict to a structured data field within the scope of your engine.
<Facet>
<FacetItem>
<Label name="videos" mode="BOOST">
<Rewrite>more:p:metatags-article-keyword:121</Rewrite>
</Label>
<Title>Videos</Title>
</FacetItem>
</Facet>

OpenXML escaping in constructor of Body element

I am instantiating an OpenXML body element using a string that looks like so (the structure is valid, part of it is omitted for readability:
bodyString:
<w:body>
...
<w:customXml w:uri="http://www.cito.nl/citotester" w:element="xhtmlElementToOpenXml" xml:space="preserve">
<p xmlns="http://www.w3.org/1999/xhtml">replace words between <></p>
</w:customXml>
<w:customXml w:uri="http://www.cito.nl/citotester" w:element="xhtmlElementToOpenXml" xml:space="preserve">
<p xmlns="http://www.w3.org/1999/xhtml"><To be></p>
</w:customXml>
...
</w:body>
Dim b as New Body(bodyString)
If I then read b.OuterXml the value is:
b.OuterXml:
<w:body>
...
<w:customXml w:uri="x" w:element="y" xml:space="preserve">
<p xmlns="http://www.w3.org/1999/xhtml">replace words between <></p>
</w:customXml>
<w:customXml w:uri="x" w:element="y" xml:space="preserve">
<p xmlns="http://www.w3.org/1999/xhtml"><To be></p>
</w:customXml>
...
</w:body>
The < and > in the first paragraph remain unchanged and those in the second paragraph are changed into the less/greater than symbols. This results in an unclosed To Be element, and therefore invalid XML.
Anyone who knows a way to not have the escaped characters from the second paragraph changed?
EDIT: I created a issue in the project's GitHub so they are aware of this, as I also get the same problem: Issue

Marklogic Attribute range Index scope

I am using the attribute "ID" in my search query. So I plan to create the attribute range index for attribute "ID" for the below sample XML.
<head>
<title>
<note ID=20 >1</note>
<to>Tove</to>
<from>Jani</from>
<heading>Reminder</heading>
<body>Don't forget me this weekend!</body>
</title>
</head>
My question is which tag (<Head> or <Title> or <Note>) I need to refer as "Parent Local Name" to have maximum effect.
the note element, because the ID is an attribute within this element
The <head> or <title> tags do not contain any attribute, the attribute belongs to the <note> tag.
Also, you can query this attribute range index through this
cts:search(//head,
cts:element-attribute-value-query(
xs:QName("note"),
xs:QName("ID"),
"20"))

How to compute an href value with Diazo rules

I am trying to change the hrefs of certain <a> elements in the theme by computing the URLs using values I select from the content. However, I can't figure out how to change the href attribute at all. It seems like the attributes attribute is not understood in the <replace> rule.
Ultimately, I would like to be able to do something like:
<replace css:theme="a.languageswitcher" attributes="href">
<!-- use some XSL logic here to stitch together the new href -->
</replace>
So the following rules work, but are useless to me:
<copy attributes="href" css:theme="a.languageswitcher" css:content="#portal-logo" />
<merge attributes="href" css:theme="a.languageswitcher" css:content="#portal-logo" />
But this one already does not work, the attributes="href" makes it so this rule is ignored.
<replace attributes="href" css:theme="a.languageswitcher" css:content="#portal-logo" />
On the other hand, if I try to rebuild the <a> element from scratch, then I run into the error described by #ross-patterson in his question: Diazo - Conditionally add a class to a theme element:
<replace theme="//a[#class='languageswitcher']">
<a class="languageswitcher">
<xsl:attribute name='href'>
foo
</xsl:attribute>
</a>
</replace>
produces the error:
XSLTApplyError: xsl:attribute: Cannot add attributes to an element if children have been already added to the element.
How can this be done?
Something like this ought to work:
<replace css:theme="a.languageswitcher">
<xsl:for-each css:select="a.languageswitcher">
<xsl:variable name="link">
http://example.com
</xsl:variable>
<xsl:copy-of select="." />
</xsl:for-each>
</replace>
in a theme I used this rule
<replace css:content-children="#hptoolbar-cerca"><xsl:attribute name="href">
<xsl:value-of select="//li[#id='portaltab-catalog']//a/#href" /></xsl:attribute><xsl:apply-templates select="node()"/></replace>
to modify an href of #hptoolbar-cerca with the href from another element in the content.
Maybe this could be useful for you.
Vito
My case is similar. I am happy with my theme code, only want to "replace" its href values. With XPath copied in the Chrome inspector, the simplest rule looks like this:
<copy attributes="href"
theme="/html/body/div[2]/div[1]/div/div[1]/a"
content="//*[#id='portal-logo']" />
I expect to successfully apply this trick to all the href values, but some do not work. I find these <a> elements are in the code block manipulated by JavaScript for implementing Slide effect. I remove all its related JavaScript codes, and copy its "real" XPath again, finally everything works fine as expected. Hope this helpful.

Problem with DisplayPattern in SharePoint 2010?

I am adding a new field to a list using the AddFieldAsXML method of SPFieldCollection. The method executes fine with no problem. And the column header shows up when I view the list; however the value never displays in the column. Here is what the field looks like after it has been added to the list. This xml is a snipped from the list schema derived using http://tw-s1-m4400-007:4016/_vti_bin/owssvr.dll?Cmd=ExportList&List={1F87433F-50E1-46C5-A138-00E1CF7E5801}
This code works great in 2007 but does not work in 2010. Any help would be appreciated.
<Field ID="{e24ccb96-35fd-44e5-b7d1-4150dbbc9a64}" Type="Computed" ReadOnly="TRUE"
Name="My_x0020_Status" DisplayName="MyStatus" ShowInEditForm="TRUE" ClassInfo="Icon"
AuthoringInfo="(My status)" SourceID="http://schemas.microsoft.com/sharepoint/v3"
StaticName="MyStatus" FromBaseType="TRUE">
<FieldRefs>
<FieldRef Name="ID" />
<FieldRef Name="Title" />
</FieldRefs>
<DisplayPattern>
<HTML>
<![CDATA[ <a href="form.htm?ID="
]]>
</HTML>
<Column Name="ID" />
<HTML>
<![CDATA[ ">
]]>
</HTML>
<Column Name="Title" />
<HTML>
<![CDATA[ </a>
]]>
</HTML>
</DisplayPattern>
</Field>
This link provided a lot of help in solving this issue:
http://social.technet.microsoft.com/Forums/en/sharepoint2010customization/thread/ef0d1d22-47ff-416c-becd-13d48de80e4d
Basically, display patterns fields are defined in the C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\XSL\fldtypes.xsl file.
There is a file called fldtypes_ratings.xsl that you can use as an example of defining your custom field display.
You can create your own xsl file (i.e. fldtypes_myfile.xsl) to define your own custom display.
Here's a sample of my content:
<xsl:stylesheet xmlns:x="http://www.w3.org/2001/XMLSchema"
xmlns:d="http://schemas.microsoft.com/sharepoint/dsp" version="1.0" exclude-result-
prefixes="xsl msxsl ddwrt" ns:ddwrt="http://schemas.microsoft.com/WebParts/v2/DataView/runtime"
xmlns:asp="http://schemas.microsoft.com/ASPNET/20"
xmlns:__designer="http://schemas.microsoft.com/WebParts/v2/DataView/designer"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:SharePoint="Microsoft.SharePoint.WebControls" xmlns:ddwrt2="urn:frontpage:internal">
<xsl:template match="FieldRef[#Name='MyCustomField']" mode="Computed_body">
<xsl:param name="thisNode" select="."/>
<SPAN class="mystuff-content-item" style="Width:100%;text-align:center">
<SPAN class='mystuff-socialized-status mystuff-socialized-status-unknown'></SPAN>
<SPAN class="mystuff-content-object-type" style="display:none">
MyContent
</SPAN>
<SPAN class="mystuff-content-followed" style="display:none">0</SPAN>
<SPAN class="mystuff-content-name" style="display:none"></SPAN>
<SPAN class="mystuff-content-id" style="display:none">
<xsl:value-of select="$List" />
<xsl:text>|</xsl:text>
<xsl:value-of select="$thisNode/#ID" />
</SPAN>
</SPAN>
</xsl:template>
</xsl:stylesheet>
Hope that helps!
I'm confused as to the point of referencing these articles -- both of them state "Two legacy field types that ship with SharePoint Foundation do not have a DisplayPattern type of RenderPattern in FLDTYPES.XML: (1) ContentTypeId fields are never visible. (2) Computed fields are rendered on list views and in Display mode by a DisplayPattern element in their Field elements within the schema.xml of each list on which they appear."
The original question is clearly defined as a "Computed" field, that according to the linked articles do not use the fldttypes.xml for their renderpattern, but intstead use the DisplayPattern element just as the original question posted. It would help to post references to how the DisplayPattern works in 2010 -- since the documentation clearly states that it Does work, but never says how.
See my blog on this here: http://www.threewill.com/2012/07/computed-fields-in-sp-2010/. Hopefully this makes it clear on how to do computed fields in SP2010.
This method of customization from 2007 is made obselete by changes in 2010's rendering of fields. Read the note from the SDK entry on RenderPattern for more detail:
Important!
This topic describes markup that was used in a now obsolete method of rendering custom fields types on list views and on the Display, Edit, and New forms. It is provided solely to assist persons who are debugging a custom field type that was originally developed against an earlier version of SharePoint Foundation. For information about the recommended methods, see How to: Create Field Rendering Templates and How to: Create a Custom Field Type.
Custom fields whose rendering is defined with RenderPattern markup still render properly on forms. However, SharePoint Foundation, by default, uses XSLT stylesheets to render fields on list views, even for legacy custom fields whose list view rendering is defined with a RenderPattern. To enable the rendering of such a field, a TRUE element must be added to the containing FieldTypes element in the field type definition file (fldtype*.xml).