SAPUI5: Binding Attributes of XMLModels - data-binding

How is this done in OpenUI 5 / SAPUI5?
given the following
<MainNavigation>
<Link>
<property name="Name">Clinical Overview</property>
<property name="command">showTeachingPoints</property>
<property name="autoSelect">true</property>
</Link>
<Link>
<property name="command">showDevices</property>
<property name="Name">Equipment</property>
</Link>
</MainNavigation>
And trying to fill out the text property for the following:
<tnt:SideNavigation expanded="true" itemSelect="onItemSelect">
<tnt:NavigationList id="sideMenu" items="{/MainNavigation/Link}">
<tnt:NavigationListItem text="{property/[#name='Name']/text()}" />
</tnt:NavigationList>
</tnt:SideNavigation>
The goal should be to display the Name of each property (so Clinical Overview, Equipment, etc...) but the query is not working.
Also I've tried:
{property/[#name='Name']/text()}
{property/[name='Name']/text()}
{property/['#name='Name'']/text()}
{property[#name='Name']/text()}
The only way that's worked has been
{property}
However that will only display whatever is first in the collection of property nodes. I want to know how to get at a specific node since I want to use the other nodes for different purposes (default selection, function callback names, etc...)
edited to clarify:
The list should contain:
Clinical Overview
Equipment
Using {property/#name} the list would be:
Name
command
Granted this is not what I'm looking for but it shares the same problem as {property} in that it returns only the first item under <Link> when I may want the second or third.
This xpath query works in other places /UI/MainNavigation/Link/property[#name='Name']/text() and I would just like to how to translate that into OpenUI.

This should do the trick:
<tnt:SideNavigation expanded="true" itemSelect="onItemSelect">
<tnt:NavigationList id="sideMenu" items="{/MainNavigation/Link}">
<tnt:NavigationListItem text="{property/#name}" />
</tnt:NavigationList>
</tnt:SideNavigation>
More info in the docs about Binding Path Syntax for XML Models.
For attributes, a special selector using the "#" character exists and "text()" can be used to reference the content text of an element. Lists are referenced by using the path to the multiple element.
BR Chris

Related

Improve performance of query with range indexes in eXist-db

Reading the docs http://exist-db.org/exist/apps/doc/indexing.xml
I'm finding difficult to understand how and if I can improve the performances of a 'read' query (with 2 parameters: a string and an integer).
Do eXist-db have a default structural index? Can I improve a 2 params query with a 'range index'?
More details about my XML db (note there are 2 different dbs simply merged on the same root):
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<db>
<docs>
<doc>
<header>
<year>2001</year>
<number>1</number>
<type>O</type>
</header>
<metas>
<meta>
<number>26001</number>
<details>
<detail>
<description>legge</description>
<number>19</number>
<date>14/01/1994</date>
</detail>
<detail>
<description>decreto legge</description>
<number>453</number>
<date>15/11/1993</date>
</detail>
</details>
</meta>
</metas>
</doc>
<doc>
<header>
<year>2001</year>
<number>2</number>
<type>O</type>
</header>
<metas>
<meta>
<number>26002</number>
<details>
<detail>
<description>decreto legislativo</description>
<number>29</number>
<date>03/02/1993</date>
</detail>
</details>
</meta>
<meta>
<number>26016</number>
<details>
<detail>
<description>decreto legislativo</description>
<number>29</number>
<date>03/02/1993</date>
</detail>
</details>
</meta>
</metas>
</doc>
</docs>
<full_text_docs>
<doc>
<header>
<year>2001</year>
<number>1</number>
<type>O</type>
<president>ferrari</president>
</header>
<text>lorem ipsum ...
</text>
</doc>
<doc>
<header>
<year>2001</year>
<number>2</number>
<type>O</type>
<president>ferrari</president>
</header>
<text>lorem ipsum......
</text>
</doc>
</full_text_docs>
</db>
This is my xquery
xquery version "3.0";
let $doc := doc("/db//index_test/test_general.xml")//db/docs/doc
let $fulltxt := doc("/db//index_test/test_general.xml")//db/full_text_docs/doc
return <root> {
for $a in $doc[metas/meta/details/detail[date="03/02/1993" and number = "29"]]/header
return $fulltxt[header/year/text()=$a/year/text() and
header/number/text()=$a/number/text() and
header/type/text()=$a/type/text()
]
} </root>
Basically I simply find for the detail/number and detail/date that matches the input in the first db and take the results for querying the second db. The results are all the <full_text_header> documents that matches.
I would to know if I can create indexes for the fields number and date to improve performance. Note this is the ONLY query I need to optimize (the only I do on this db) obviously number and date changes :).
SOLUTION:
For a clear explanation read the joewiz answer. My problem was the correct recognition of the .xconf file. It have to be placed in /db/yourcollectiondir. If you're using eXide when you create the file you should select Xml type with template "eXist-db collection configuration". When you try to save the file you will see a prompt "Apply configuration?" then click 'ok'. Just then run this xquery xmldb:reindex('/db/yourcollectiondir').
Now if all it's right when you run an xquery involving an index you will see the usage in "Monitoring and profiling".
As that documentation page states, eXist does create a structural index for all XML stored in the database. This is not an index of values, though, so without further indexes, queries based on value (rather than structure) would involve a lookup of values in the DOM. As your data grows larger, looking up values in the DOM gets slower and slower. This is where value-based indexes, such a range index, saves the day. (For a fuller explanation, see the "Indexing" section of Wolfgang Meier's "Tuning the Database" article, which is essential for getting the most performance out of eXist.)
So, yes, you can create indexes for the <number> and <date> fields. I'd recommend the "new range" index, as described on that documentation page. Your collection.xconf file setting up these indexes would look like this:
<collection xmlns="http://exist-db.org/collection-config/1.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<index>
<range>
<create qname="number" type="xs:integer"/>
<create qname="date" type="xs:string"/>
</range>
</index>
</collection>
You have to store this within the /db/system/config/ collection, in a subcollection corresponding to the location of your data in the database. So if your data is located in /db/apps/myapp/data, you would place this collection.xconf file in /db/system/config/db/apps/myapp/data.
Note that the configuration here would only affect the for clause's queries of date and number values, and not the predicates in the return clause, which depend on the values of <year> and <type> elements. So, to ensure your query maximized the use of indexes, you should declare indexes on these; it seems that xs:integer would be the appropriate type for each.
Lastly, I would suggest eliminating the /text() steps, which are completely extraneous. For more on the use/abuse of text(), see Evan Lenz's article, "text() is a code smell".
Update (2016-07-17): With the updated code sample above, I have a couple of additional suggestions. First, since the code is in /db/index_test, we will store our files as follows:
Assuming you're using eXide, when you store the collection.xconf file in a collection, eXide will prompt you to have a copy of the file placed in the correct location in /db/system/config. If you're not using eXide, you need to store the collection.xconf file there yourself.
Using the unmodified query, I can confirm that despite the presence of the collection.xconf file, monex shows no indexes are being applied:
Let's make a few modifications to the file to ensure indexes are properly applied:
xquery version "3.0";
<root> {
for $a in doc("/db/index_test/test_general.xml")//detail[date = "03/02/1993" and number = 29]/ancestor::doc/header
return
doc("/db/index_test/test_general.xml")/db/full_text_docs/doc
[
header/year = $a/year and
header/number = $a/number and
header/type = $a/type
]
} </root>
With these modifications, monex shows that indexes are applied to the comparisons in the for clause:
The insights here are derived from the "Tuning the Database" article. To get full indexing for all comparisons, you will need to define additional indexes and may need to make similar modifications to your query.
One final note: the version of monex you see in these pictures is using a feature I added this weekend, called "Tare", which tries to filter out other operations from the query profiling results in order to help the user see just the effects of their own query. This feature is still just a pull request, so running the current release version, you won't see identical results.

In jjtree, is there a way to traverse the generated parse tree and track changes to the value

I'm new to JJTree parsing. I've gone through basics. In jjtree, is there a way to traverse the generated parse tree and track changes to the value?
Say for example I've a JJTree which produces the following tree structure:
<parent name="xx">
<child age="21" family="true">
</child>
<parent>
<parent name="xy">
<child age="21" family="true">
</child>
<parent>
Here, i'd like to change the family as "false" for parent having name "xy". I'm struggling in this part.
My code needs a similar change. As my code increases complexity to understand, I've given here a sample which is understandable.
To traverse the tree, you can use a visitor object. See the documentation.

Update SearchableText index on dexterity type

I am trying to update SearchableText on my dexterity type ("Resource"), to include file contents from child items, by adding this to resource.py:
#indexer(IResource)
def subFiles(obj):
searchable_text = obj.SearchableText()
for item in obj.getFolderContents({'portal_type': 'File'}, full_object=True):
searchable_text += item.SearchableText()
return searchable_text
grok.global_adapter(subFiles, name="SearchableText")
I know I need an event to update this, but believe I should be able to see the index modified by manually "clearing and rebuilding" from the ZMI, however no changes take place on the value of SearchableText for objects of this content type. I am not seeing any errors either, so I am not sure where the problem lies.
Well, I did not recognise here, that you are using dexterity.
You need the dexteritytextindexer behavior:
https://github.com/collective/collective.dexteritytextindexer
Enable this on your container type.
<property name="behaviors">
<element value="collective.dexteritytextindexer.behavior.IDexterityTextIndexer" />
</property>
With the dexteritytextindexer you have a different approach to index the data on your container. Check the dexteritytextindexer.IDynamicTextIndexExtender.

how to set publish dcp for child or other publications to different location without overiding all other settings

I am trying to configure cd_storage and getting issue in setting up dynamic component presentation as they get over written by child and published to same folder from every publication.
I know we can define the publication level settings but once we define that then it expect us to define everything inside that publication tag. We do not want to define every thing 50 times in publication tag.
Could any one suggest the best practice for same.
this is for sdl tridion 2011 sp1
Thanks in advance...
Your problem is in how you defined your storage configuration for the storage which you use to store ComponentPresentations. There is a flag in the definition of a storage which sets exactly this type of behavior: defaultFilesystem. You probably have it set to false which causes all ComponentPresentations from all publications to be stored in the same location. By setting this flag to true you will get ComponentPresentations from different publications stored in different locations. I will give an example to show how this works in cd_storage_conf.xml:
<Storage Type="filesystem" Class="com.tridion.storage.filesystem.FSDAOFactory" Id="defaultCPs" defaultFilesystem="true">
<Root Path="c:\temp\cpRoot" />
</Storage>
....
<ItemTypes defaultStorageId="defaultFile" cached="true">
<Item typeMapping="ComponentPresentation" itemExtension=".jsp" storageId="defaultCPs"/>
....
This is really easy to maintain and will make the Broker to store ComponentPresentations to locations like: c:\temp\cpRoot\pub109\dcp\jsp\*** (here I have publicationId=109).
Hope this helps.

Reading menu items from XML in asp.net

I am building a multilingual web site which will provide four languages. I will be using an asp:MenuItem control. For each language I want to read menu items' names from an XML document.
XML draft can be thought as the following:
<root>
<language>
<en>
<home>
<link>Default.aspx</link>
<text>Home</text>
</home>
<about>
<link>About.aspx</link>
<text>About</text>
</about>
</en>
<de>
<home>
<link>Default.aspx</link>
<text>Hauptseite</text>
</home>
<about>
<link>About.aspx</link>
<text>Über</text>
</about>
</de>
</language>
</root>
I am not sure if the syntax and construction are correct. My other goal is about menu items order. The order must be same for all languages.
I want to know how to realize this. OR is there another and/or better way to do this.
Also my database is ready for content for both languages.
I do not want to work with if-else conditions. Thanks for your help.
If all languages should be the same structure, I would suggest a slightly different XML.
This groups the different names for the different languages together, which should be easier to manage should you need to change anything.
<root>
<item>
<link>default.aspx</link>
<text>
<en>Home</en>
<de>Hauptseite</de>
</text>
</item>
<item>
<link>about.aspx</link>
<text>
<en>About</en>
<de>Über</de>
</text>
</item>
</root>

Resources