greetings all
i have some rules which are very similar
<rule>
<from>/a/**/b/**/c/**/d</from>
<to>/somePlace</to>
</rule>
<rule>
<from>/a/**/b/**/c</from>
<to>/anotherPlace1</to>
</rule>
<rule>
<from>/a/**/b</from>
<to>/anotherPlace2</to>
</rule>
and i want when an exact match occurs for the first rule, it's only executed and the other rules are not, like break in programming, any ideas how to do so ?
Have you tried changing the first rule to instruction to:
<to last="true">/somePlace</to>
If you are using OCPsoft Rewrite URLRewriteFilter, you can achieve this same thing using the Lifecycle control:
.defineRule()
.when(Direction.isInbound().and(Path.matches("/some/{page}/")))
.perform(Forward.to("/new-{page}/"));
If we want to stop processing rules, we can mark the lifecycle as "handled," and no further rules will be processed.
.defineRule()
.when(Direction.isInbound().and(Path.matches("/other/{page}/")))
.perform(Lifecycle.handled());
Subsequently, we can also use the Lifecycle.proceed() or Lifecycle.abort() controls to continue processing even if previously marked handled (in the same rule) or terminate the request completely (aborting the entire HttpServletRequest,) respectively.
the rules are executed in order - if it matches the first rule it will execute it, if it doesnt it will go to the next and so on
therefore you need to order your rules by priority and that should help
paul
Related
How to define the style of objects in a collection for one record via SLD. For example, lines are separate, polygons are separate.
For instance
<Rule>
<ogc:PropertyIsEqualTo>
<ogc:Function name="geometryType">
<ogc:PropertyName>geom</ogc:PropertyName>
</ogc:Function>
<ogc:Literal>GeometryCollection</ogc:Literal>
</ogc:PropertyIsEqualTo>
<PolygonSymbolizer> -- ONLY POLIGON
...
</PolygonSymbolizer>
<LineSymbolizer> -- ONLY LINES
...
</LineSymbolizer>
</Rule>
So far, it turns out that the first style is used for all sub-objects of the recording, and the lines are displayed as polygons.
https://i.stack.imgur.com/RoHBZ.png
A Rule will apply all of its Symbolizers to all features that match its filter, so this SLD is behaving exactly as expected.
You need to have multiple rules with different filters:
<Rule>
<ogc:PropertyIsEqualTo>
<ogc:Function name="geometryType">
<ogc:PropertyName>geom</ogc:PropertyName>
</ogc:Function>
<ogc:Literal>Polygon</ogc:Literal>
</ogc:PropertyIsEqualTo>
<PolygonSymbolizer> -- ONLY POLIGON
...
</PolygonSymbolizer>
</Rule>
<Rule>
<ogc:PropertyIsEqualTo>
<ogc:Function name="geometryType">
<ogc:PropertyName>geom</ogc:PropertyName>
</ogc:Function>
<ogc:Literal>LineString</ogc:Literal>
</ogc:PropertyIsEqualTo>
<LineSymbolizer> -- ONLY LINES
...
</LineSymbolizer>
</Rule>
There are more details in the GeoServer manual, however, none of these techniques will work with a GeometryCollection so you will probably need to rework your data flow to avoid ending up with these.
I'm working on a project where I need to harvest some data from website, so I'm using webharvest.
I'm running into a problem where the data I'm harvesting (comments from news websites) is sometimes across more than one page. I'm trying to configure it to look for the link to the second page of comments in the xpath of the webpage. Problem is, if I try an if test, the condition always passes, and if I try a try statement, the try body always succeeds. This results in my script extracting comments from the first page (if there is only one), twice. Articles with two sets of comments work beautifully, however. So my question relates to the syntax of if conditions and try statements. The documentation on Webharvest is scant with regard to these functions.
Here's what I'm trying. First, the if test:
<var-def name="secondPageLink">
<xpath expression="/a[#class='next']/#href">
<var name="firstPage"/>
</xpath>
</var-def>
<case>
<if condition="${secondPageLink != null}">
[ process second page ]
</if>
</case>
Second, the try/catch:
<try>
<body>
<var-def name="secondPageLink">
<xpath expression="/a[#class='next']/#href">
<var name="firstPage"/>
</xpath>
</var-def>
[ continue to process page ]
</body>
<catch>
</catch>
</try>
The problem with the if test is that despite the fact that the variable is empty when no second page exists (which I can see from the debugging in the gui), the if seems to return true, and runs its body.
I can more easily see why the try/catch doesn't work properly, since an xpath returning no value (if the second page doesn't exist) wouldn't constitute an 'error' as such and the try will still succeed. A further difficulty is that the #href of the next page link is relative, and so needs to be appended to the URL of the first page (or the base URL of the article, actually, but same thing here), meaning that my html-to-xml takes the url ${firstPage}${secondPageLink}, which ends up simply being the first page URL again, and webharvest thus processes the first page a second time.
If someone can reformulate my if test to return false when the secondPageLink xpath returns an empty value, I'd be very appreciative!
Found an answer.
This person had a similar problem with if, and an answer there suggested using the syntax: condition="${variable.toString().length() > 0}".
So in my code, replacing the if test with:
<case>
<if condition="${secondPageLink.toString().length() > 0}">
<var-def name="secondPageFull">
<html-to-xml>
<http url="${commentedArticleURL}${secondPageLink}"/>
</html-to-xml>
[...]
produced the correct result.
How would I obtain a node using Xpath that sometimes has irrelevant nodes in between goal nodes.
I have xml file typically in the form as following:
<body>
<target>
<goal>Text I want to obtain</goal>
</target>
<target2>
<goal>Second Target I want to obtain</goal>
</target2>
<body>
And I need to throw target's goal and target2's goals in separate string.
So I got the "Text I want to obtain" using Xpath "//body/target/goal", and got the "Second Target I want to obtain" using Xpath "//body/target2/goal".
Very simple.
However later I found out that in between target and goal (or target 2 and goal) there could be separate nodes (not known) as following:
<body>
<target>
<annoying>
<goal>Text I want to obtain</goal>
</annoying>
</target>
<target2>
<noidea>
<goal>Second Target I want to obtain</goal>
</noidea>
</target2>
<body>
I still have to distinguish the two targets so I cannot just accumulate goal with "//goal". What kind of 2 Xpaths wold I need to obtain each text I need to obtain?
Thank you very much in advance
Use a wildcard between target/target2 and goal:
//body/target/*/goal
//body/target2/*/goal
I wanted to use "bpws:getVariableData()" to assign a value only if the xpath expression find a match. If not, nothing should happen. Unfortunately the bpel processing stops with a fault, if the xpath expression finds no match. Is there a way to achieve this behavior?
Thanks for your help.
I found that the oracle BPEL engine provides a feature to ignore missing from data. This Flag can be added to the copy element as follows:
<copy bpelx:ignoreMissingFromData="yes|no"/>
More info on how to set it in the JDeveloper: http://download.oracle.com/docs/cd/E17904_01/integration.1111/e10224/bp_manipdoc.htm#SOASE87087
This solves the problem with the fault message that is thrown. However it still does not show the wanted behavior. My intension was that no assignment is done, if the xpath expression cannot be evaluated. Using the bpelx:ignoreMissingFromData flag however assigns the empty string "" to the target.
In my use case I want to merge tow XML documents. I want to assign a new value to an element in document1 only if the element shows up in document2. If not, leave the element in document1 unchanged.
I solved the problem using a transformation instead of a BPEL assign. In the xsl I use the following statement. The transformation gets two XML documents a input. Document1 is referenced via the parameter $parameter_referenceDocument1.
<elementName>
<xsl:if test="xpathInDocument2">
<xsl:value-of select="xpathInDocument2"/>
</xsl:if>
<xsl:if test="not(xpathInDocument2)">
<xsl:value-of select="$parameter_referenceDocument1.xpathInDocument1"/>
</xsl:if>
</elementName>
I know its ugly, but solves the problem. If anyone has a better solution, please let me know.
No, the BPEL standard requires the engine to throw a selectionFailure in this case. To avoid such situations, make sure you have properly initialized variables and/or validate variable against a schema. Also you may guard an assign activity with an if/switch activity to check for the presence of the element before accessing it. You may also consider writing an custom XPath function that returns a default value in case the demanded element does not exist in the variable. However, I'm not sure if the Oracle BPEL engine supports that.
You can create a scope around the assign activity and using an exception handler on the scope catch the selectionFailure, the item which will then carry on processing.
In the exception handler you could then assign a default value if required.
To clarify Vanto's statement, the Oracle BPEL engine does support custom XPath functions which would allow you to do that.
I have been looking around the site a bit, but I didn't find any replies on how to do it the way I want.
What I want is an URL like this:
www.example.com/Projects/"querystring1 - text only"/"querystring2 - 4 digits only"/
to show the page with this URL:
www.example.com/Projects.aspx?Region=querystring1&Zip=querystring2
What I have been trying is the following:
<rewrite url="~/Leje-og-udlejning-arbejdskraft/(.+)/(.+)" to="~/Workers.aspx?Region=$1&zip=$2"/>
But it just takes both of them as one querysting and put them in the Region-querystring.
I'd need to see the rest of your rewrite rules to be sure, but if you have multiple rewrites (i.e. to handle situations where users only specify one of the two query strings) neglecting to add processing="stop" at the end will cause one rule to override the other.
For example, I use the following setup in my web.config file:
<rewriter>
<rewrite url="~/(.+)/(.+)" to="~/Default.aspx?ref=$1&page=$2" processing="stop"/>
<rewrite url="~/(.+)" to="~/Default.aspx?ref=$1" processing="stop"/>
</rewriter>
This will first check to see if 2 query variables are present. If they are, it rewrites them appropriately and stops processing other rules. This is the biggie. Without processing="stop" at the end, I end up passing both as the ref query string. This might be the conflict you're running in to.