<document>
<para>
<heading id="1" type="new" level="1" />
<span />
<heading id="2" type="new" level="2" />
<span />
</para>
<para>
<heading id="3" type="new" level="1" />
<span />
<heading id="4" type="new" level="2" />
<span />
</para>
<para>
<heading id="5" type="old" level="2" />
<span />
</para>
<para>
<heading id="6" type="old" level="2" />
<span />
</para>
<para>
<heading id="7" type="old" level="2" />
<span />
</para>
<para>
<heading id="8" type="old" level="2" />
<span />
</para>
<para>
<span />
</para>
</document>
Hello,
I'm parsing the above XML node-by-node in Javascript. Assuming that I'm currently at "heading id='8'" node, how would I look backwards and find the first node that has it's level set to "2" (same as the level on the node that I'm currently parsing) and type set to "new" using XPath expressions?
So, in the above exapmple, the element with id="4" must be selected.
Thanks!
You can use preceding axis and use index to return only the nearest preceding element :
preceding::*[#level='2' and #type='new'][1]
xpathtester demo
output :
<heading id="4" level="2" type="new"/>
In the demo, I use //*[#id='8'] to select element with id=8 first, to simulate context element, and then continue selecting the target element using the above mentioned XPath.
Actually I thought you wanted this.
How would I look backwards and find the first node that has it's level set to the same as the level on the node that I'm currently parsing and type set to new using XPath expressions?
Oh well, leaving this here for future reference ...
[#type='new' and #level=current()/#level]
Related
In odoo I try to change the recruitement form, but some of the stuctural elements dont have a name or id. When I change those elements it works fine initially, but when I upgrade the database then the rendering of the xml is stricter for some reason and gives an ParseError.
The recruitement form:
<sheet>
<div class="oe_button_box" name="button_box"/>
<div class="oe_title">
<label for="name" class="oe_edit_only"/>
<h1><field name="name" placeholder="e.g. Sales Manager"/></h1>
</div>
<notebook>
<page string="Job Description">
<div attrs="{'invisible': [('state', '!=', 'recruit')]}">
<label for="description"/>
<field name="description" type="html"/>
</div>
</page>
<page name="description_page" string="Description">
<field name="description" type="html"/>
<div class="d-none oe_clear"/>
</page>
<page string="Recruitment">
<group>
<group name="recruitment">
<field name="company_id" options="{'no_create': True}" groups="base.group_multi_company"/>
<field name="department_id"/>
</group>
<group>
<field name="no_of_recruitment"/>
</group>
</group>
</page>
</notebook>
</sheet>
As you can see; the sheet, notebook, pages and groups mostly dont have a name. The string attribute is also not sufficient to modify with a expression in xpath. So it feels like I'm just stuck with this framework.
What I try:
<xpath expr="//sheet/notebook" position="replace">
<notebook>
<page name="description_page" string="Description">
<field name="description" type="html"/>
<div class="d-none oe_clear"/>
</page>
<page string="Recruitment">
<group>
<group name="recruitment">
<field name="branch_concept" />
<field name="branch" />
<field name="department_id" />
</group>
<group>
<field name="no_of_recruitment"/>
</group>
</group>
</page>
</notebook>
</xpath>
And this works until I do a db upgrade, then I get a parseError.
Does anybody know I can use my own structure?
In the xpath expression you use //<some_node> to 'Selects nodes in the document from the current node that match the selection no matter where they are'. You can also use /<some_node>/<some_other_node> to locate a specific element.
for example /form/sheet/notebook/page[1]
My portlet-model-hints.xml below stipulates that quantity is required, that works fine.
Now I also want to stipulate that quantity must be made of digits:
<model-hints>
<model name="com.example.model.MyEntity">
[...]
<field name="order" type="long">
<validator name="required" />
<validator name="digits" /> <----- Does not work
</field>
[...]
</model>
</model-hints>
PROBLEM: Adding <validator name="digits" /> makes the text field disappear.
Is there a problem in my syntax? Should I do the validation in the JSP instead? By the way here is the JSP form to add/edit my entity:
<aui:form action="<%= editMyEntityURL %>" method="POST" name="fm">
<aui:fieldset>
[...]
<aui:input name="quantity" />
[...]
</aui:fieldset>
[....]
</aui:form>
[Workaround, I am still looking for a better solution]
Not elegant at all, but moving digits validation to the JSP works:
<aui:form action="<%= editMyEntityURL %>" method="POST" name="fm">
<aui:fieldset>
[...]
<aui:input name="quantity">
<aui:validator name="digits"/>
</aui:input>
[...]
</aui:fieldset>
[....]
</aui:form>
It must be done in all JSP forms that use the entity.
I used APEX 4.2 to create a Gantt chart with the AnyGantt Library.
When i use a custom XML for the Anygantt Diagram everythign works fine. As soon as i want to use custom datagrids, the collapser is missing.
My XML is the following:
<anygantt> <settings>
<navigation enabled="True" position="Top" size="30">
</navigation>
<editing allow_edit="true">
<rounding>
<date unit="Week" step="1" />
</rounding>
</editing>
<locale>
<date_time_format week_starts_from_monday="True">
<months>
<names>January,February,March,April,May,June,July,August,September,October,November,December</names>
<short_names>Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec</short_names>
</months>
<week_days>
<names>Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday</names>
<short_names>Sun,Mon,Tue,Wed,Thu,Fri,Sat</short_names>
</week_days>
<format>
<full>%yyyy.%MM.%dd.%HH.%mm.%ss</full>
<date>%yyyy.%MM.%dd</date>
<time>%HH.%mm.%ss</time>
</format>
</date_time_format>
</locale>
</settings>
<datagrid enabled="true" width="300">
<columns>
<column attribute_name="Name" width="200" cell_align="Left">
<header>
<text>Name</text>
</header>
<format>{%Name}</format>
</column>
<column width="40" cell_align="Left">
<header>
<text>Stunden</text>
</header>
<format>{%Stunden}</format>
</column>
</columns>
</datagrid>
<styles>
<defaults>
<period>
<period_style>
<bar_style>
<labels>
<label anchor="Center" valign="Center" halign="Center">
<text>{%DISPO} %</text>
<font face="Verdana" size="10" bold="true" color="White">
</font>
</label>
</labels>
</bar_style>
</period_style>
</period>
</defaults>
<period_styles>
<period_style name="test">
<bar_style>
<labels>
<label anchor="Center" valign="Center" halign="Center">
<text>Center</text>
<font face="Verdana" size="10" bold="true" color="White">
</font>
</label>
</labels>
<middle shape="Full">
<fill enabled="true" type="Solid" color="DarkSeaGreen" />
<border enabled="true" color="#FF0000" />
</middle>
</bar_style>
</period_style>
</period_styles>
</styles>
<resource_chart><resources><resource name="AVI" id="5"/>
<resource name="CAB" id="4"/>
<resource name="Test, Test (Test)" id="3-U837751" parent="3"/>
<resource name="PL" id="3"/>
<resource name="Struktur" id="2"/>
</resources><periods><period resource_id="3-U837751" name="NAME-3-U837751" start="2015.07.28 00:00" end="2015.07.31 00:00">
<attributes>
<attribute name="DISPO"><![CDATA[,5]]></attribute>
</attributes>
</period></periods></resource_chart>
You need to add cell_align="LeftLevelPadding" to the column where you want to see the collapser. Something like:
<column attribute_name="Name" width="200" cell_align="LeftLevelPadding">
This is described in KB: http://support.anychart.com/customer/portal/articles/2077851--anygantt-4-x-collapser-is-missing-in-datagrid-column
You can find more info on columns at
http://6.anychart.com/products/anygantt/docs/users-guide/index.html?columns.html
I'm trying to extract data from the following structure:
<span>Heading</span>
<br />
<br />
<span>Heading1</span>
<br />
data#1
<br />
<br />
<span>Heading4</span><br />
• data#4.1
<br />
• data#4.2
<br />
• data#4.3
<br />
• data#4.4
<br />
<br />
<span>Heading5</span>
<br />
• data#5.1
<br />
• data#5.2
<br />
• data#5.3
<br />
<br />
I can extract data#1 using something like this:
span[text()='Heading1']/following-sibling::br[1]/following::text()[1]
But I cant figure out how to extract the data under Heading4. I need to extract data#4.1, data#4.2, data#4.3 & data#4.4.
The number of points is not fixed and can vary.
This XPath 1.0 expression selects exactly the wanted nodes:
/*/span[.='Heading4']
/following-sibling::text()
[count(.|/*/span[.='Heading5']/preceding-sibling::text())
=
count(/*/span[.='Heading5']/preceding-sibling::text())
]
[normalize-space()]
It is produced from the well-known Kayessian method for intersection of two nodesets $ns1 and $ns2:
$ns1[count(.|$ns2) = count($ns2)]
We obtain the first expression above if in the Kayessian formula we substitute $ns1 with:
/*/span[.='Heading4']/following-sibling::text()
and $ns2 with:
/*/span[.='Heading5']/preceding-sibling::text()
The final predicate [normalize-space()] filters out the whitespace-only text nodes from this intersection.
XSLT-based verification:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:copy-of select=
"/*/span[.='Heading4']
/following-sibling::text()
[count(.|/*/span[.='Heading5']/preceding-sibling::text())
=
count(/*/span[.='Heading5']/preceding-sibling::text())
]
[normalize-space()]
"/>
</xsl:template>
</xsl:stylesheet>
When this transformation is applied on the provided XML document (with the entities replaced -- as we don't have a DTD defining them available and this isn't essential here):
<html>
<span>Heading</span>
<br />
<br />
<span>Heading1</span>
<br /> data#1
<br />
<br />
<span>Heading4</span>
<br /> #acirc;#euro;#cent; data#4.1
<br /> #acirc;#euro;#cent; data#4.2
<br /> #acirc;#euro;#cent; data#4.3
<br /> #acirc;#euro;#cent; data#4.4
<br />
<br />
<span>Heading5</span>
<br /> #acirc;#euro;#cent; data#5.1
<br /> #acirc;#euro;#cent; data#5.2
<br /> #acirc;#euro;#cent; data#5.3
<br />
<br />
</html>
the Xpath expression is evaluated and the result of this evaluation is copied to the output:
#acirc;#euro;#cent; data#4.1
#acirc;#euro;#cent; data#4.2
#acirc;#euro;#cent; data#4.3
#acirc;#euro;#cent; data#4.4
You can use
span[text()='Heading4']/following-sibling::text()[. != ""]
to get all the text after Heading4 and then use.
span[text()='Heading5']/following-sibling::text()[. != ""]
to get the text after Heading5 that you don't want, and then subtract the second result set from the first in your main program.
And if you have XPath 2, you can exclude them directly with the except operator:
span[text()='Heading4']/following-sibling::text()[. != ""] except span[text()='Heading5']/following::text()[. != ""]
You can get only the data without the • before with the substring(.,5) function, so the final XPath 2 expression becomes:
(span[text()='Heading4']/following-sibling::text()[. != ""] except span[text()='Heading5']/following::text()[. != ""])/substring(., 5)
And since you haven't explicitly said your language requirement you might also want to look at my pascal based query language, because it is imho way much nicer:
<span>Heading4</span><br />
<t:loop>
{filter(text(), "data.*")}<br/>
</t:loop>
<br/>
<span>Heading5</span><br />
I finally ended up using this, with help from the answer here
//text()[preceding-sibling::span[1] = 'Heading4']
I'd use
span[text()='Heading4']/following-sibling::text()
and then parse resulting text separately.
I'm working with XUL, and below is abasic slider/scale implementation:
<scale value="1" min="1" max="10" increment="1"/>
However I want a numbox next to it which displays the value selected in the slider, and maybe I didn't look hard enough in the XUL tutorial, but I couldn't find a feasible answer.
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<window id="yourwindow"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<scale value="1" min="1" max="10" increment="1" id="a"/>
<textbox readonly="true" observes="a"/>
</window>