How to define the style of objects in a collection for one record via SLD - geoserver

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.

Related

XSD Verify Element has at least one of the attributes specified

Using XSD schema validation 1.0 I want to verify an element has at least one attribute specified.
For example, a simple element like this:
<foo a="1" b="2" c="3" />
I want to verify that at least attribute b or c is specified. But note that both can also be specified--they're not mutually exclusive.
I tried using a key along the lines of:
<xs:key name="AttributeSpecified">
<xs:selector xpath="." />
<xs:field xpath="#b|#c" />
</xs:key>
but it fails when both attributes are specified (because multiple results are returned).
Can it be done?
This is not possible in XSD 1.0. It might be possible in XSD 1.1.
I am a fan of XML Schema, but I would not choose it for this type of validation. You might be able to make it work using XSD1.1 but if your requirements became just a little more complex you could end up with some horrible-looking constraints.
On the other hand, an XPath expression can elegantly express any constraint you can think of, and you would not need to bend the language to make it work.

FHIR Profile/StructDef: How are children (sub-elements) of a named slice tied to the slice?

I'm trying to figure out how to fully specify a sliced element. If I'm reading the spec right, nameReference is the only place where a "sub element" of a slice can declare which slice it's "on".
So, if telecom is sliced by use and system and I want to specify a constraint on home phone, I have to fix use and system to those values and then add my constraints on that slice.
Consider:
Resource Example ElementDefinition attributes
================================ =====================================================================
<Patient> name="Patient"
... snip ...
<telecom> name="HomePhone"
<system value="phone" /> name="HomePhone.system", nameReference="HomePhone", fixedCode="phone"
<use value="home" /> name="HomePhone.use" , nameReference="HomePhone", fixedCode="home"
<value value="5551234567" /> name="HomePhone.value" , nameReference="HomePhone"
</telecom>
... snip ...
</Patient>
In most examples, it appears that a dotted notation of Name has been used (as I've placed in the example). But the specification doesn't require this and provides no format that could be reliably parsed.
The problem is: nameReference and fixed[x] are mutually exclusive. What's the correct way to handle this??
Repetitions in an instance don't "declare" what slice they're part of. They simply declare the appropriate value for what ever element(s) are the discriminator for the slicing process. nameReference isn't involved at all. On the definition side, association is simply handled by name. So HomePhone.system is associated with HomePhone simply by the name and by sequential proximity. The dot-notation is required. We could probably be a bit more explicit about that though, so feel free to submit a change request.

How to form Xpath with irrelevant nodes in between two target nodes

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

Nodes with case-insensitive content using XOM

I want to query nodes from a XOM document which contains certain value but case insensitive. Something like this:
doc.query('/root/book[contains(.,"case-insentive-string")]')
But it contains is case sensitive.
I tried to use regexes, but it is
only XPATH2.0 and XOM does not seem
to support it.
I tried
contains(translate(."ABCEDF...","abcdef..."),"case-insentive-string")]'
failed too.
I tried to match
subnodes and read parent attributes
using getParent, but there is no
method to read parents attributes.
Any suggestions ?
If you are using XOM, then you can use Saxon to run XPath or XQuery against it. That gives you the ability to use the greatly increased function library in XPath 2.0, which includes functions lower-case() and upper-case(), and also the ability (though in a somewhat product-specific way) to choose your own collations for use with functions such as contains() - which means you can do matching that ignores accents as well as case, for example.
2.I tried contains(translate(."ABCEDF...","abcdef..."),"case-insentive-string")]'
failed too.
The proper way to write this is:
/root/book[contains(translate(., $vUpper, $vLower),
translate($vCaseInsentiveString, $vUpper, $vLower)
)
]
where $vUpper and $vLower are defined as (should be substituted by) the strings:
'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
and
'abcdefghijklmnopqrstuvwxyz'
and $vCaseInsentiveString is defined as (should be substituted by) the specific case-insensitive string.
For example, given the following XML document:
<authors>
<author>
<name>Victor Hugo & Co.</name>
<nationality>French</nationality>
</author>
<author period="classical" category="children">
<name>J.K.Rollings</name>
<nationality>British</nationality>
</author>
<author period="classical">
<name>Sophocles</name>
<nationality>Greek</nationality>
</author>
<author>
<name>Leo Tolstoy</name>
<nationality>Russian</nationality>
</author>
<author>
<name>Alexander Pushkin</name>
<nationality>Russian</nationality>
</author>
<author period="classical">
<name>Plato</name>
<nationality>Greek</nationality>
</author>
</authors>
the following XPath expression (substitute the variables by the corresponding strings):
/*/author/name
[contains(translate(., $vUpper, $vLower),
translate('lEo', $vUpper, $vLower)
)
]
selects this element:
<name>Leo Tolstoy</name>
Explanation: Both arguments of the contains() function are converted to lower-case, and then the comparison is performed.

URLRewriteFilter & Break after some rule

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

Resources