The question is in the title .
I don't understand what getNodes() return. If it was a list, i see how to go through but i don't know what to do the Object...
I'd like to get the name of my node parsing the Dom with UIComponent Tree.
Look doc here.
It returns either a List (or something that is Iterable) or a Map.
Related
I have the following XML:
<envelope>
<action>INSERT</action>
<auditId>123</auditId>
<payload class="vendor">
<fizz buzz="3"/>
</payload>
</envelope>
I am trying to write an XPath expression that will pluck out vendor (value for the payload's class attribute) or whatever its value is.
My best attempts are:
/dataEnvelope/payload[#class="vendor"]#class
But this requires the expression to already know that vendor is the value of the attribute. But if the XML is:
<dataEnvelope>
<action>INSERT</action>
<auditId>123</auditId>
<payload class="foobar">
<fizz buzz="3"/>
</payload>
</dataEnvelope>
Then I want the expression to pluck out the foobar. Any ideas where I'm going awry?
If you need #class value from payload node, you can use
/dataEnvelope/payload[#class]/#class
or just
/dataEnvelope/payload/#class
At first, your two XML files are out-of-sync - one references envelope and the other references dataEnvelope. So exchange one for the other, if necessary.
So, to get the attribute value of payload, you can use an XPath expression like this which uses a child's attribute value to be more specific:
/envelope/payload[fizz[#buzz='3']]/#class
Output is:
vendor
If the document element can/will change, then you can keep the XPath more generic and select the value of the class attribute from the payload element that is a child of any element:
/*/payload/#class
If you know that it will always be a child of envelope, then this would be more specific(but the above would still work):
/envelope/payload/#class
I have been at this for hours and I cannot make any progress.
I do not know how to do the following, I am used to arrays and loops, not nokogiri objects.
I want to select the table element immediately after the h2 containing span with id == "filmography"
<h2><span id ="filmography>...
<table> # What I want to find
<tr>
<td>...
So far I have used
objects = page.xpath("//h2" | "//table")
to have an array of nokogiri objects and I test each for id == "Filmography" and would work with the next object, however the elements returned are not in order as they appear on the page they are in the order all h2's then all tables.
Could I somehow have all 'h2's and 'table's as element objects in the order they appear on the page, and test the child object 'span' for its id attribute?
All advice appreciated, as I am thoroughly stuck.
This looks like it should work:
page.xpath('h2//span[#id="filmography"]').first.next_element
Nokogiri supports CSS selectors, which make this easy:
doc.at('span#filmography table').to_html
=> "<table><tr>\n<td>...</td>\n </tr></table>"
doc.at('#filmography table').to_html
=> "<table><tr>\n<td>...</td>\n </tr></table>"
at returns the first matching node, using either a CSS or XPath selector.
The "NodeSet" equivalent is search, which returns a NodeSet, which is like an Array, but would force you to use first after it, which only really makes for a longer command:
doc.search('span#filmography table').first.to_html
doc.search('#filmography table').first.to_html
Because the span tag contains an id parameter, you're safe to use at and only look for #filmography, since IDs are unique in a page.
I'm loading data using jQuery (AJAX), which is then being loaded into a table (so this takes place after page load).
In each table row there is a 'select' link allowing users to select a row from the table. I then need to grab the information in this row and put it into a form further down the page.
$('#selection_table').on('click', '.select_link', function() {
$('#booking_address').text = $(this).closest('.address').text();
$('#booking_rate').text = $(this).closest('.rate').val();
});
As I understand it, the 'closest' function traverses up the DOM tree so since my link is in the last cell of each row, it should get the elements 'address' and 'rate from the previous row (the classes are assigned to the correct cells).
I've tried debugging myself using quick and dirty 'alert($(this).closest(etc...' in many variations, but nothing seems to work.
Do I need to do something differently to target data that was loaded after the original page load? where am I going wrong?
You are making wrong assumptions about .closest() and how .text() works. Please make a habit of studying the documentation when in doubt, it gives clear descriptions and examples on how to use jQuery's features.
.closest() will traverse the parents of the given element, trying to match the selector you have provided it. If your .select_link is not "inside" .address, your code will not work.
Also, .text() is a method, not a property (in the semantical way, because methods are in fact properties in Javascript). x.text = 1; simply overrides the method on this element, which is not a good idea, you want to invoke the method: x.text(1);.
Something along these lines might work:
var t = $(this).closest('tr').find('.address').text();
$('#booking_address').text(t);
If #booking_address is a form element, use .val() on it instead.
If it does not work, please provide the HTML structure you are using (edit your question, use jsFiddle or a similar service) and I will help you. When asking questions like this, it is a good habit anyways to provide the relevant HTML structure.
You can try using parent() and find() functions and locate the data directly, the amount of parent() and find() methods depends on your HTML.
Ex. to get previous row data that would be
$('#selection_table').on('click', '.select_link', function(){
$('#booking_address').text = $(this).parent().parent().prev().find('.address').text();
});
Where parent stands for parent element (tr), then prev() as previous row and find finds the element.
Is there a demo of the code somewhere? Check when are you calling the code. It should be after the 'success' of AJAX call.
Maybe someone can help, is it a way to combine an xPath expression to query node by it's property value?
I have a node with custom property "ItemId". I need something like this:
uQuery.GetNodesByXPath("//* [#itemId = '<someId>']")
Thanx in advance!
"//*" Will give you all nodes, so "//*[#itemId = '<someId>']" is asking to give you all nodes with an attribute equal to exactly "<someId>", which you can't have as a valid attribute.
So, if you have <myNode someId='my Id value'></myNode> , then try //*[#itemId='someId']
But remember, this will give you ANY node with that particular attribute ID.
I'm not sure if this is what you're looking for, but please post your XML or a snippet of what you're grabbing, as that will clear up any grey areas.
I am trying to design a generalized detail page for an object.
In the controller class I find the list of all child relations of that object.
I then want to create for each child relations found and for accomplishing this I will have to dynamically set the value of list attribute within it.
For example :
<apex:relatedList subject={!ObjName} list="{!relatedListName}" />
But the problem here is that list attribute only accepts String literal, so can't implement it. Please suggest a way for this requirement to be accomplished.
Yes, you can dynamically set the value of the "list" attribute on a relatedlist tag, and you do so via Dynamic Visualforce. This question has since been asked and concisely answered here on the Salesforce Stack exchange for any future browsers:
https://salesforce.stackexchange.com/questions/7531/apexrelatedlist-list-dontexistinallorgs-c-only-solveable-with-dynamic
Here is the general solution:
In a custom controller, add a function to dynamically generate the RelatedList markup. I will assume from your wording that you have already accessed the full list of child relationships in your controller, so in order to spit out all the lists in one block, I would use something like this:
public Component.Apex.OutputPanel getDynamicList()
{
Component.Apex.OutputPanel outPanel = new Component.Apex.OutputPanel();
for(String id : childNames) {
Component.Apex.RelatedList relList = new Component.Apex.RelatedList();
relList.list = id;
outPanel.childComponents.add(relList);
}
return outPanel;
}
In the middle there, you can dynamically set any string to the "List" value, and by iterating through your list of strings, you are adding related list objects over and over again. (To simply add one list, remove the for loop, and make the "id" string value whatever specific relationship you wish to display).
Then on your visualforce page, you can render this block out using a dynamic visualforce tag:
<apex:dynamicComponent componentValue="{!DynamicList}" />
(as you may know, the formulaic value field will dig up the getter automatically)
Great success!
I would suggest trying apex:dataTable or apex:repeat to build your own list display. You will likely need a wrapper class to handle passing attributes and values from the sObject to the page.