I have an XML Field that contains data similar to how .Net constructs controls within forms. Suppose you have a windows Form, you can add multiple controls to the form and they show up under the .Controls property. Some of the controls themselves can also have controls such as panels, group boxes etc. Similar to what is shown in the xml below.
<Form>
<Name>MyForm</Name>
<TabCtrl>
<Name>Tab1</Name>
<Controls>
<TextboxCtrl>
<Name>MyTextBox</Name>
<Location>3,10</Location>
<Tag>34</Tag>
</TextboxCtrl>
<Label>
<Name>MyLabel</Name>
<Location>23,3</Location>
<Tag>19</Tag>>
</Label>
<Panel>
<Name>myPanel</Name>
<Controls>
<TextboxCtrl>
<Name>MyTextBox2</Name>
<Location>36,210</Location>
<Tag>34</Tag>
</TextboxCtrl>
</Controls>
</Panel>
</Controls>
</TabCtrl>
<TabCtrl>
<Name>Tab2</Name>
<Controls>
...
</Controls>
</TabCtrl>
There are thousands of rows in a DB table each with xml that itself consists of up sometimes 1000’s of “controls”. I’m looking for a way to query for TabCtrl/Name node when that TabCtrl contains a control that has the Tag of 34.
I can limit the rows by this query using xPath
Select theXML from ViewTable where theXML.exist('//Tag[.="34"]') = 1
Further, I can get the Name of the control rather than the entire xml with this:
Select theXML.query('//*[Tag="34"]/Label/text()') as 'Control Name'from ViewTable where theXML.exist('//Tag[.="34"]') = 1
How do I get the TabCtrl/Name ? The path from the element that contains the matching Tag could go through 1-n levels of Controls nodes so using the Xpath statement won’t work. The TabCtrl will all ways be a direct child of the Form node
Possible Solutions :
One possible way to get the text from TabCtrl/Name containing a control that has the Tag of 34 :
Select theXML.query('//TabCtrl[Controls/*/Tag="34"]/Name/text()') as 'Control Name'
Or if you need to get to the <TabCtrl> starting from it's descendant then you can always climb up the tree using parent::element_name or ancestor::element_name or .. :
Select theXML.query('//*[Tag="34"]/ancestor::TabCtrl/Name/text()') as 'Control Name'
Difference between axes mentioned above :
parent::element_name : Go one level up to a specific parent element
ancestor::element_name : Go one or more level up to a specific ancestor element
.. : Go one level up to a parent element with any name
Shred the XML on Form/TabCtrl using nodes(), check the existence of Tag=34 for each shredded node using exist() and finally get the value from Form/TabCtrl/Name with the value() function.
select TC.X.value('(Name/text())[1]', 'nvarchar(100)')
from YourTable as T
cross apply T.theXML.nodes('/Form/TabCtrl') as TC(X)
where TC.X.exist('*//Tag/text()[. = "34"]') = 1
SQL Fiddle
This query will return the TabCtrl/Name for any TabCtrl that has a Controls node that has a grand child Tag that =s 34:
DECLARE #theXML XML = '<Form>
<Name>MyForm</Name>
<TabCtrl>
<Name>Tab1</Name>
<Controls>
<TextboxCtrl>
<Name>MyTextBox</Name>
<Location>3,10</Location>
<Tag>34</Tag>
</TextboxCtrl>
<Label>
<Name>MyLabel</Name>
<Location>23,3</Location>
<Tag>19</Tag>>
</Label>
<Panel>
<Name>myPanel</Name>
<Controls>
<TextboxCtrl>
<Name>MyTextBox2</Name>
<Location>36,210</Location>
<Tag>34</Tag>
</TextboxCtrl>
</Controls>
</Panel>
</Controls>
</TabCtrl>
<TabCtrl>
<Name>Tab2</Name>
<Controls>
...
</Controls>
</TabCtrl>
</Form>'
Select #theXML.query('//TabCtrl/Controls/*[Tag="34"]/../../Name') as 'Control Name'
Output:
<Name>Tab1</Name>
I'm not 100% sure that's what you're looking for, but this is probably the general pattern you want to follow here, with an additional query if you need to get more deeply nested Tag=34 nodes.
Related
I have a salesforce query which returns contact information. I need to save the data in 2 tables. In the first table I have to store some metadata about the contacts in an intermediate state. I then get the auto-generated metadata table ID from the metadata saved and apply it to every contact. I then have to save the contact data into a database table and then finally update the contacts metadata to its final state. The problem is that there is a lot of data so I have to include a fetch size when performing this process. What I want to achieve should be something like this, please note this is only what I am looking to achieve. How can I know that the fetch contacts is complete, so that I can save the final state? How can I structure the flow for transactions?
Ideally, I would like to pass the ConsumerIterator to a Java component where I can easily control the process. Can I pass a reference of the ConsumerIterator to a Java component for example? If I can how can I do so?
<sfdc:query fetchSize="100" config-ref="sfdc-connector"
query="dsql:SELECT Id, Account.Id,
Account.Name, Account.PersonEmail, Account.LastName From Contact" />
dw:transform-message metadata:id="d1f6ab4f-4b40-4e30-ae" doc:name="trnsfm">
<enricher target="variable:metaInfo">
<flow-refname="getContactMetadata"/>
</enricher>
<dw:set-payload><![CDATA[%dw 1.0
.//Rest of transformer
<db:insert config-ref="MySQL_Configuration" doc:name="Save Metatdata">
...
</db:insert>
<db:insert config-ref="MySQL_Configuration" doc:name="Save contacts">
....
<db:insert>
<db:insert config-ref="MySQL_Configuration" doc:name="Update Metadata
Final State">
....
<db:insert>
</flow>
Problem Solved. I wrote a Java Component, implementing Callable and grabbed the ConsumerIterator. I then was able to use the iterator to obtain items in fetchSize. I then used Spring Jdbc since the data model is simple enough to transactionally save the data
I'm having the two types of check-boxes one is for selectAll check-box in the data table header, and another type selecting the check-box for each row.
I'm doing a operation, So I need to show the confirmation message, How do I get the count of the selected check-boxes from the Managed Bean.
My code was written in JSF 1.2.
I can able to do select all records, select records, ManagedBean is working fine, But I need to get how many of them got selected for deletion.
Here is the JSF code,
<i:commandLink id="delete"
onclick="if (!confirm('#{managedBean.deleteSelectedCount}')) return false;"
action="#{managedBean.deleteRecords}"
title="Delete records"
immediate="true">
<i:graphicImage url="images/icons/delete.gif" alt="Delete records" />
</i:commandLink>
;
;//Some coding
;
//Data table code starts
<i:dataTable id="caseDataTable"
<h:column>
<f:facet name="header">
<i:selectBooleanCheckbox id="selectAllRecords" title="select All records"
value="#{managedBean.selectAll}">
<a4j:support event="onclick" reRender="caseDataTable,globalMessages" action="#{managedBean.actionSelectAllRecordss}" onsubmit="showBusyIndicator();" oncomplete="hideBusyIndicator();" />
</i:selectBooleanCheckbox>
</f:facet>
<h:outputLabel for="selectCheckbox" value="selectCheckbox"/>
<i:selectBooleanCheckbox id="selectCheckbox"
title="select a record" value="#{managedBean.selected}" >
<a4j:support event="onclick" reRender="selectAllRecords, globalMessages" action="#{managedBean.actionSelectionChange}"
onsubmit="showBusyIndicator();" oncomplete="hideBusyIndicator();"/>
</i:selectBooleanCheckbox>
</h:column>
Possible solution is to use h:inputHidden component (I think it exists in JSF 1.2. If not, you can find some alternative).
For example
Add h:inputHidden to the page
<h:inputHidden id="selectedCountHidden" value="#{managedBean.deleteSelectedCount}"/>
Each time you click on header check box or any of row check boxes, calculate deleteSelectedCount value and re-render h:inputHidden. Something like
<i:selectBooleanCheckbox id="selectCheckbox" title="select a record" value="#{managedBean.selected}" >
<a4j:support event="onclick" reRender="...,selectedCountHidden,..."
And now, since h:inputHidden will always hold deleteSeletedCount value, you can read its value via java script so there is no need for re-loading the page when you click on commandLink
<i:commandLink id="delete"
onclick="if(!confirm(document.getElementById('form:selectedCountHidden').value))return false;"..../>
Note that if you have form with id defined, you will need to call
document.getElementById('form:selectedCountHidden').value
Otherwise just call
document.getElementById('selectedCountHidden').value
In any case, inspect page source and you will find the exact id of p:inputHidden.
I need to access the input field in the below html. The way the page is setup I need to chain using the 'Address Line 1' text and then sending text to the input field. The input field id changes and so doesn't the layout of the fields depending on user preference. I am struggling. If you need some more information feel free to ask I did not want to overload with too much information.
<td class="labelCol requiredInput">
<label for="00N36000000xina"><span class="assistiveText">*</span>Address Line 1</label>
</td>
<td class="dataCol col02">
<div class="requiredInput">
<div class="requiredBlock"></div>
<input id="00N36000000xina" maxlength="255" name="00N36000000xina" size="20" tabindex="4" type="text">
</div>
</td>
I have accessed like this:
element(by.css('div.pbSubsection:nth-child(3) > table:nth-child(1) > tbody:nth-child(1) > tr:nth-child(2) > td:nth-child(2) > input'))
However depending on where the user puts the fields it can move around. So what I was hoping was to be able to access the label\ and use that to pinpoint its input field.
I don't know protractor but I cobbled together some code that hopefully will work or be close and I'll give you the thought process and some info and hopefully you can use it to fix my code, if needed, and solve the problem.
Start by finding an element by XPath, "//label[text()='Address Line 1']". This searches for a LABEL tag that contains "Address Line 1". Once you find that element, get the label attribute. From your HTML, this label is the id for the INPUT element you want. Now use the id to find the element and do with it what you want.
id = element(by.xpath("//label[text()='Address Line 1']")).getAttribute("label")
input = element(by.id(id))
input.sendkeys("some text")
Haven't tested this myself, but you could try something like this:
// $ is shorthand for element(by.css())
$('div.assistiveText').getAttribute('for').then(function (val) {
// locate the <input> by the value of the attribute on <label>
element(by.id(val)).sendKeys('abc'); // replace sendKeys with your intended function
});
Or if that first locator on the label isn't specific enough, swap out $('div.assistiveText') for element(by.cssContainingText('Address Line 1'))
I tried it for other attributes (I don't have a for attribute anywhere in my app) and it seemed to work for me.
Try this:
List<WebElement> elementList = driver.findElements(By.cssSelector("tbody > tr"));
for (WebElement element : elementList) {
if(element.findElement(By.cssSelector("td.labelCol > label")).getText().equalsIgnoreCase("Address Line 1")) {
element.findElement(By.cssSelector("input[type='text']")).sendKeys("textToInput");
}
}
I have created a new module in Odoo for helpdesk and I have 2 problems that I can't seem to fix or find information on so need some help.
I created a status bar (code):
state = fields.Selection({('new','New'), ('open','In Progress'), ('closed','Closed')}, "Status")
_defaults = {
'state': 'new'
}
<header>
<field name="state" widget="statusbar" statusbar_visible="new,open,closed" clickable="True"/>
Even thought I have stated "new, open, closed" it is showing in Odoo as open,new, closed.
I set the state default as new, even though I am not getting any errors, when I click on create it shows state as blank.
Any ideas on how to fix these issues?
When you declared your field you gave it a set of options instead of a list of options. Sets in Python doesn't keep the information about items order, but lists do. For your declared order to be respected you just need to replace the set literal by a list literal:
state = fields.Selection(
[('new','New'), ('open','In Progress'), ('closed','Closed')],
"Status",
)
You can remove statusbar_visible from your view.
As for your second problem (with the default value) Emipro Technologies is correct. You need to declare the default value as an argument on your field:
state = fields.Selection(
[('new','New'), ('open','In Progress'), ('closed','Closed')],
default='new',
string="Status",
)
Your fields declaration seems that it's Odoo-8 code, in V8 _defaults is not there you need to write as below,
state = fields.Selection({('new','New'), ('open','In Progress'), ('closed','Closed')},"Status", default='new')
And there is no more logic to set sequence in status bar but then also try this,
<form string="String" version="7.0">
<header>
<field name="state" widget="statusbar" statusbar_visible="new,open,closed" clickable="True"/>
</header>
</form>
Has anyone tried to dynamically select which properties they want to write to an entity on appengine? For example:
I have a web form with 5 fields, and any given user will fill out some subset of those fields. I POST only the fields with data to the server (e.g. Fields 1,2,4). On the server side, how do I elegantly write only properties 1,2, and 4? The Model class has a function that returns a dictionary of property names (Model.properties()), but how would I use it to select property names?
In SQL, I would build an INSERT or UPDATE statement by matching the fields POSTed against the Model.properties() dictionary. I would look at the db module code in the Appengine SDK, to see if the Model class had some collection of Property objects, but I can't find the module on my disk (I'm a little new to python and appengine).
Update: I read trunk/google/appengine/ext/db/init.py which confirmed that there is no way to refer to the properties as a group. Anyone know of a workaround?
Any thoughts?
Update2: This question was answered on the Google Group for AppEngine: http://groups.google.com/group/google-appengine/browse_thread/thread/b50be862f6d94b6e#
The python module will look something like this:
from google.appengine.ext.db import Key
from google.appengine.api.datastore import Get, Put
def edit_item(request, db_id):
objKey = Key(str(db_id))
if request.method == 'POST':
objEntity = Get(objKey)
for k, v in request.POST.iteritems():
objEntity[k]=v
Put(objEntity)
return HttpResponseRedirect('/')
query = TestModel.get(objKey)
return render_to_response('edit.html', ({'modify_data': query,}))
Your HTML should look something like this:
<form method="POST" action="." enctype="multipart/form-data">
Title: <input type="text" name="title" value="{{modify_data.field1}}"/>
Text: <input type="text" name="txt" value="{{modify_data.field2}}"/>
<input type="submit"/>
</form>