Read elements from XMLList in flex - apache-flex

is it possible to read elements what i have circled in image. I need this because XmlLists what i receive from the system is dynamic.Their elements are not static.I can't use methods like
for each(var item:XML in dp)
{
var element:String=item.#date.toString;
}
i cannot use #date always because XMLList content change always. date , open , close names are not getting always .

This is my sample XML
private var testXML:XML=<main>
<item name= "agent1" tag="cpu" value="39"/>
<item name= "agent2" tag="cpu" value="17"/>
<item name= "agent3" tag="cpu" value="27"/>
<item name= "agent4" tag="cpu" value="39"/>
<item name= "agent5" tag="cpu" value="17"/>
<item name= "agent6" tag="cpu" value="27"/>
</main>;
This sample code shows how i achieved
var List:XMLList=testXML.children();
var attr:XMLList=List.attributes();
for(var i:Number=0;i<List[0].attributes().length();i++)
{
Alert.show(attr[i].name());
}

You Can use this syntax
var str_attr:String = "#date"; // or any things you define
for each(var item:XML in dp)
{
var element:String=item[str_attr].toString();
}

Related

SAPUI5 How to display only the first value of an entitySet

I'm currently working on an app for displaying some data, which I get from an EntitySet.
The mockup for my application looks like this:
On the top, I have an input Field with a button to apply the filter with the value of the input.
After that, there are 5 ObjectListItems at the moment. I don't know if its the right thing to use.
Under these boxes, there is a table to display further information about the chosen entry. The table works as intended and looks good.
My Problem now lies within these 5 Boxes.
{Binding1} to {Binding5} contains always the same Value for one giving "Input Value". Which means, {Binding1} for example would be 7 times Value1 and {Binding2} 7 times Value2. Now i want these to be shown only one time in there own Box.
Values, which are differ per row, are shown in the table below.
I don't know how I could make this work...
View:
<l:VerticalLayout width="100%">
<l:BlockLayout background="Dashboard">
<l:BlockLayoutRow>
<l:BlockLayoutCell width="100%">
<Title text="Test {Binding1} - {Binding2}"/>
</l:BlockLayoutCell>
</l:BlockLayoutRow>
<l:BlockLayoutRow>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Site"
icon="sap-icon://building"
title="{Binding3}"
/>
</l:BlockLayoutCell>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Adress"
icon="sap-icon://addresses"
title="{Binding4}"
/>
</l:BlockLayoutCell>
</l:BlockLayoutRow>
<l:BlockLayoutRow>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Supplier"
icon="sap-icon://supplier"
title="{Binding5}"
/>
</l:BlockLayoutCell>
<l:BlockLayoutCell width="50%">
<ObjectListItem
intro="Currency"
icon="sap-icon://lead"
title="{Binding6}"
/>
</l:BlockLayoutCell>
</l:BlockLayoutRow>
</l:BlockLayout>
</l:VerticalLayout>
<Table
id="table1"
items="{path: '/EntitySet'}">
<columns>
<Column>
<Text text="Category"/>
</Column>
...
</columns>
<items>
<ColumnListItem>
<cells>
<Text text="{Category}"/>
...
</cells>
</ColumnListItem>
</items>
</Table>
Controller:
return Controller.extend("com.zf.cmi.zz1ui5_ivdp.controller.View", {
onInit: function() {
},
onPress: function() {
var oTable = this.getView().byId("table1");
var oTableBinding = oTable.getBinding("items");
var filter = new sap.ui.model.Filter("InvoiceNo", sap.ui.model.FilterOperator.EQ, this.byId("search").getValue());
oTableBinding.filter(filter);
}
});
Is there a way to show the value of {Binding1} - {Binding5} only one time at their given Box?
*edit
As an addition, the result of my XML model would look like this:
Entry1: Entry2: Entry3:
Binding1 = a Binding1 = a Binding1 = a
Binding2 = b Binding2 = b Binding2 = b
Binding3 = ... Binding3 = ... Binding3 = ...
Binding10 = 1 (Table) Binding10 = 2 Binding10 = 3
If It's a JSON Model you can use binding path like this {/Binding1/0}.
If It's a XML Model you need to know the KEY to set the binding path like this {/Binding1('Key')}. If you don't know the key, you have to use JS in controller to get it or change/create your service to return the data in an away better to you UI5 show it.
Using JS Controller
onInit: function () {
this.getView().bindElement({
path: "/BINDING_PATH",
events: {
dataReceived: function (oEvent) {
var data = oEvent.getParameter('data');
var array_paths = oEvent.getSource().getModel();
}.bind(this),
}
});
}
Now on data you have all data returned by service, and on array_path you have an array with path and data, you can get the array KEY (that's the service path) to binding to your controls.
<ObjectListItem
intro="Site"
icon="sap-icon://building"
title="{/EntrySet('1')/Binding3}" />
is the same as
<ObjectListItem
binding="{/EntrySet('1')}"
intro="Site"
icon="sap-icon://building"
title="{Binding3}" />
is the same as
<ObjectListItem
id="Item3"
intro="Site"
icon="sap-icon://building"
title="{Binding3}" />
const iID = 1;
const sKey = "/EntrySet('" + iID + "')";
this.byId("Item3").bindElement(sKey);
You can then replace iID with something meaningful depending on the input.

Tridion DynamicContent.Query Searching By Component Template

I'm trying to render all component presentations from the broker database with a certain component template. Here's the query code so far:
using Tridion.ContentDelivery.DynamicContent;
using Tridion.ContentDelivery.DynamicContent.Query;
ItemTemplateCriteria CTCriteria = new ItemTemplateCriteria(1111);
PublicationCriteria pubCriteria = new PublicationCriteria(10);
AndCriteria finalCriteria = new AndCriteria(pubCriteria, CTCriteria);
Response.Write("<h1>START</h1>");
Query q = new Query();
q.Criteria = finalCriteria;
string[] result = q.ExecuteQuery();
if (result != null && result.Length > 0)
{
foreach (string r in result)
{
Response.Write("<h1>" + r + "</h1>");
}
}
else {
Response.Write("Result is null or 0-length.");
}
Response.Write("<h1>END</h1>");
I keep getting null results. I do have dynamic content publishing setup in cd_storage_conf.xml and a few component presentations published in the Broker database.
My understanding from this document is that, I should be able to retrieve related component URIs using this approach.
My Questions:
Is my understanding of the capabilities of the Query class correct?
Did I miss anything, config and code-wise?
Is there any other way of retrieving broker content by component template?
EDIT:
Additional info: Regarding ItemTemplateCriteria, I only assumed that this is used for searching records by Component Template. I assumed because there is another criteria class called PageTemplateCriteria. Please correct me if this assumption is invalid.
EDIT:
Additional info: I've inspected the COMPONENTS, SCHEMA and TEMPLATES tables in the broker database but didn't find the published components there. By default rule in the cd_storage_conf.xml, published content must go to the broker. For reference, here's my config:
<Publication Id="57" defaultStorageId="brokerdb" cached="false">
<Item typeMapping="ComponentPresentation" storageId="brokerdb" cached="false" />
<Item typeMapping="BinaryMeta" cached="true" storageId="brokerdb"/>
<Item typeMapping="BinaryVariant" cached="true" storageId="brokerdb"/>
<Item typeMapping="Binary" storageId="defaultFile" cached="true"/>
<Item typeMapping="ComponentMeta" cached="true" storageId="brokerdb"/>
<Item typeMapping="ComponentPresentationMeta" cached="true" storageId="brokerdb"/>
<Item typeMapping="ItemMeta" cached="true" storageId="brokerdb"/>
<Item typeMapping="LinkInfo" cached="true" storageId="defaultDataFile"/>
<Item typeMapping="DynamicLinkInfo" cached="true" storageId="defaultDataFile"/>
<Item typeMapping="Page" cached="true" storageId="defaultFile"/>
<Item typeMapping="PageMeta" cached="true" storageId="defaultDataFile"/>
<Item typeMapping="Reference" storageId="brokerdb"/>
<Item typeMapping="Schema" storageId="brokerdb"/>
</Publication>
Double check your cd_storage_conf.xml and database to check the items are stored there. If your data is going to the file system it will not be query-able.
Specifically I think the ComponentPresentationMeta must be going to the DB for this scenario to work.
Also check your cd_licenses.xml file, if it is expired, if it is (even if the cd_storage_conf.xml is correct), the items will end up on the file system.

add data to a qml XmlDataModel

gi, i have a question about qml and the XmlDataModel.
i have a xml file where i have something like this:
<model>
<item title="one" />
<item title="two" />
</model>
and i have a listView which has this data:
ListView {
id: listView
dataModel: XmlDataModel {
source: "data/model1.xml"
}
}
now i dant to add some data to this model when i e.g. press a button. how to make this?
XmlListModel is a read-only model by design. However, you can use it to conveniently fetch data and fill with that data a ListModel which is mutable model. You can find an example here.

Fill dropdown list from xml with linq

i have the following xml doc:
<?xml version="1.0" encoding="utf-8" ?>
<dropdowns>
<dropdown name="DropDownLoc">
<menu text="Select" value="-1" />
<menu text="North" value="1200" />
<menu text="South" value="1400" />
</dropdown>
<dropdown nome="DropDownEsp">
<menu text="Select" value="-1" />
<menu text="Est" value="7" />
<menu text="Ovest" value="9" />
</dropdown>
</dropdowns>
I want to read this xml and fill two dropdowns with a method given the dropdownlist name (like "DropDownEsp")
I want to accomplish this with linq, who can help me please ?
Below is code which would help you read XML and create a list of items (ListItem):
// or use XDocument.Parse("xml string") to parse string
XDocument xdoc = XDocument.Load(#"c:\testxml.xml");
var dropLists = xdoc.Descendants("dropdown")
.Select(d => d.Descendants("menu").Select(m =>
new /* new ListItem(text, value) */
{
Text = m.Attribute("text"),
Value = m.Attribute("value")
}))
.ToList();
Try adding items into controls yourself.
If you have an empty <asp:DropDownList ID="DynamicDropDown" runat="server" /> control on your .aspx page, you can data bind it a the results of a LINQ query like this:
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
// Assuming your XML file is in the App_Data folder in the root of your website
string path = Server.MapPath("~/App_Data/DropDowns.xml");
// Let's say we want to use the options from the second <dropdown>-tag in your XML
string whichDropDown = "DropDownEsp";
// This is the LINQ query to find those options from the XML
// and turn them into ListItem objects
var query =
from dropDown in XDocument.Load(path).Descendants("dropdown")
where dropDown.Attribute("name").Value == whichDropDown
from name in dropDown.Descendants("name")
let text = name.Attribute("text").value
let value = name.Attribute("value").value
select new ListItem(text, value);
// Now we data bind the query result to the control
DynamicDropDown.DataSource = query;
DynamicDropDown.DataBind();
}
}
In the LINQ query we first select only the <dropdown> element with the right name (based on the whichDropDown variable). Then we select all the <name> elements, and from each one we put the attributes in the text and value values. Then we use these values to create a new ListItem (one is created for each <name> element).
This result can then be used to data bind the <asp:DropDownList> control.

Removing duplicates in Flex 4 XMLList with filterfunction

I have seen numerous examples on how to remove duplicates in ArrayCollection but I can't seem to transpose this to XMLList. In most ArrayCollection examples, the example compares the key of the array with hasOwnProperty method and return a bool. That's fine, but what would I compare to when using an XMLList? Let's say I have:
<fx:XML id="testXML" xmlns="">
<universe>
<category cname="cat 1">
<item iname = "All"/>
<item iname = "item 1"/>
<item iname = "item 2"/>
</category>
<category cname="cat 2">
<item iname = "All"/>
<item iname = "item 3"/>
<item iname = "item 4"/>
</category>
</universe>
</fx:XML>
[actionscript]
var myList:XMLList = testXML..#iname;
will give two occurences of the item "ALL".
I know I might have to convert the XMLList to an XMLListCollection to use the filterFunction (how would I go about doing that - or should I just define myList as an XMLListCollection right from the start). then on to the filterFunction:
private function remove Duplicate (item:Object): Boolean
{
here I don't know how to compare the item to tell me if the object already exist
or not. I guess I need to compare the item to a copy of the list and see if the
item has already been seen in the copy of the list. Or is there a clean way to
do this?
}
then all this is passed to a dropDownList:
<s:DropDownList id="myDDL" dataProvider="{myList}" />
Using E4x filter function you can for example put the key into an Object (if the key is a String, otherwise use a dictionary instead of an Object) and look if it is already present to build your XMLList :
var xml:XML=<universe>
<category cname="cat 1">
<item iname="All"/>
<item iname="item 1"/>
<item iname="item 2"/>
</category>
<category cname="cat 2">
<item iname="All"/>
<item iname="item 3"/>
<item iname="item 4"/>
</category>
</universe>
function filter(xml:XML):XMLList {
var seen:Object={}
return xml..#iname.(!seen[valueOf()]&&(seen[valueOf()]=true))
}
trace( filter(xml) )
Here a live example at wonderfl : http://wonderfl.net/c/10xr
The easiest way I know how to do this is to use ActionLinq. This code will take your e4x code and turn it into an Enumerable, cast the attributes as strings, make the items in the list distinct and dump it out as an ArrayCollection.
myList = Enumerable.from(testXML..#iname)
.cast(String)
.distinct()
.toArrayCollection();
If you don't want to use ActionLinq, you can implement this using a Dictionary:
[Bindable]
private var myList:ArrayList;
private function removeDuplicates(data:XMLList):ArrayList {
var result:ArrayList = new ArrayList();
var found:Dictionary = new Dictionary();
for each(var item:String in data) {
if(item in found) {
continue;
}
found[item] = true;
result.addItem(item);
}
return result;
}
And then when the XML is ready, you can call it:
myList = removeDuplicates(testXML..#iname);

Resources