Need to finding overlapping dates in XML code - xpath

I need help finding the overlapping dates in this XML code. I need to make sure that the End date is not less than or equal to the proceeding Start Date.
<Inventory>
<StatusApplicationControl Start="2019-07-18" End="2019-07-18" InvTypeCode="STDX" />
<InvCounts>
<InvCount CountType="2" Count="9" />
</InvCounts>
</Inventory>
<Inventory>
<StatusApplicationControl Start="2019-07-18" End="2019-07-19" InvTypeCode="STDX" />
<InvCounts>
<InvCount CountType="2" Count="8" />
</InvCounts>
</Inventory>
I have tried the following code.
<rule context="Inventory">
<report test="translate(StatusApplicationControl/#Start, '-', '') <= translate(preceding::Inventory/preceding::StatusApplicationControl/#End, '-', '')">The #Start="<value-of select="#Start"/>" and #End="<value-of select="#End"/>" dates are overlaping</report>
</rule>
I expect this message to be printed -
The Start="2019-07-18" is less than or equal to the End="2019-07-18" date
Any help is greatly appreciated!

It looks like the comments are not helping you.
The rule should be:
<rule context="Inventory">
<report
test="translate(StatusApplicationControl/#Start, '-', '')
<=translate(preceding::Inventory[1]/StatusApplicationControl/#End,'-','')"
>The #Start="<value-of select="#Start"/>" and #End="<value-of
select="preceding::Inventory[1]/StatusApplicationControl/#End"
/>" dates are overlaping</report>
</rule>
EDIT
This Schematron
<schema xmlns="http://purl.oclc.org/dsdl/schematron">
<pattern>
<title>Test dates</title>
<rule context="Inventory">
<assert
test="translate(StatusApplicationControl/#Start, '-', '')
> translate(preceding::Inventory[1]/StatusApplicationControl/#End,'-','')"
>The #Start="<value-of
select="StatusApplicationControl/#Start"
/>" and #End="<value-of
select="preceding::Inventory[1]/StatusApplicationControl/#End"
/>" dates are overlaping</assert>
</rule>
</pattern>
</schema>
With this input:
<root>
<Inventory>
<StatusApplicationControl Start="2019-07-18" End="2019-07-18" InvTypeCode="STDX" />
<InvCounts>
<InvCount CountType="2" Count="9" />
</InvCounts>
</Inventory>
<Inventory>
<StatusApplicationControl Start="2019-07-18" End="2019-07-19" InvTypeCode="STDX" />
<InvCounts>
<InvCount CountType="2" Count="8" />
</InvCounts>
</Inventory>
</root>
Output:
Pattern 'Test dates' Failed : The #Start="2019-07-18" and #End="2019-07-18" dates are overlaping.
Check in https://www.liquid-technologies.com/online-schematron-validator

Here is the SchemaTron rule that worked for me. The issue was passing preceding:: to the translate() function. When doing that I got a SchemaTron Exception.
<rule context="Inventory/StatusApplicationControl">
<report test="translate(#Start, '-', '') <= preceding::StatusApplicationControl/translate(#End, '-', '') ">The #Start="<value-of select="#Start"/>" and #End="<value-of select="#End"/>" dates are overlaping</report>
</rule>

Related

XPath 1.0 fetch the child record

Below is the XML
<on-error-continue type="APIKIT:BAD_REQUEST" enableNotifications="true" logException="true">
<set-variable value="200" doc:name="httpStatus" variableName="httpStatus" />
<set-variable value="Bad request" doc:name="logDescription" variableName="logDescription" />
<flow-ref doc:name="global-prepare-error-response-sub-flow" name="global-prepare-error-response-sub-flow"/>
</on-error-continue>
<on-error-continue type="APIKIT:TOO_MANY_REQUEST" enableNotifications="true" logException="true">
<set-variable value="200" doc:name="httpStatus" variableName="httpStatus" />
<set-variable value="Many request" doc:name="logDescription" variableName="logDescription" />
<flow-ref doc:name="global-prepare-error-response-sub-flow" name="global-prepare-error-response-sub-flow"/>
</on-error-continue>
Wanted to get the single record
"set-variable value="200" doc:name="httpStatus" variableName="httpStatus"
using xPath 1.0 expression: Parent is -->on-error-continue type="APIKIT:BAD_REQUEST" and child is -->set-variable value = "200".
Have tried below expression. It is working fine with Xpath2.0 but not working with 1.0
//*[local-name()='on-error-continue'][#*[local-name()='type' and .='APIKIT:BAD_REQUEST']]/set-variable[#value='200' and #variableName='httpStatus']
Using this handy website, I took the xml and put it in a root element, <root>YOUR XML</root>.
With this XPath:
//root/on-error-continue[#type='APIKIT:TOO_MANY_REQUEST']/set-variable[#value='200' and #variableName='httpStatus']
I was able to extract the matching record. Try it yourself and replace the root with * in the above XPath. You should see the records that you're seeking.
The wildcard operator can be used like any element in the path.

How can I use XPath to find the minimum/maximum value of an attribute for chooses group in a set of elements?

<foo>
<bar id="1" score="100" group="beginner" />
<bar id="2" score="200" group="beginner" />
<bar id="3" score="300" group="expert" />
...
</foo>
I try use like this, but something wrong (xpath 1.0)
foo/bar[#group='beginner' and not(#score<= preceding-sibling::bar/#score) and not(#score<=following-sibling::bar/#score)]
using xpath 1.0
/foo/bar[#group='beginner'][(not(preceding-sibling::bar[#group='beginner']/#score >= #score) and not(following-sibling::bar[#group='beginner']/#score > #score)) or (not(preceding-sibling::bar[#group='beginner']/#score <= #score) and not(following-sibling::bar[#group='beginner']/#score < #score))]/#score

xsd:assert (complicated character verification)

Is there a way to verify that the template contains only those characters that are passed to #param ?
I considered options with xpath functions(fn:) but have not found a suitable option.
this is 2 valid xml for example:
<rule type="myRule" template="A-B-CB">
<attribute param="B"/>
<attribute param="A"/>
<attribute param="C"/>
</rule>
<rule type="myRule" template="A(C)-B">
<attribute param="C"/>
<attribute param="A"/>
<attribute param="B"/>
</rule>
and 2 not valid xml:
<rule type="myRule" template="AB-CD">
<attribute param="A"/>
<attribute param="B"/>
<attribute param="C"/>
</rule>
<rule type="myRule" template="AC">
<attribute param="A"/>
<attribute param="B"/>
<attribute param="C"/>
</rule>
perhaps there are ideas how to implement it using schematrone or otherwise?
So the set of letters in #template must be exactly the same as the set of letters in ./attribute/#param?
That is to say, distinct-values(string-to-codepoints(replace(#template, '\P{L}', ''))) must be the same set as distinct-values(attribute/#param/string-to-codepoints()).
So how do you assert that two sequences contain the same values, under permutation?
In XPath 3.1, deep-equal(sort($X), sort($Y))
In XPath 2.0, I can't think of anything better than
empty($X[not(.=$Y)]) and empty($Y[not(.=$X)])
I'll leave you to put this all together.

Grouping in XSLT 2.0 (grouping by text)

I have a problem figuring out this grouping in xslt:
The initial information:
<Application>
<ApplicationItem LayoutPath="Attachments.Package.Attachment[bfd0b74d-2888-49d9-a986-df807f08ad8a].UniqueID" Value="bfd0b74d-2888-49d9-a986-df807f08ad8a" />
<ApplicationItem LayoutPath="Attachments.Package.Attachment[bfd0b74d-2888-49d9-a986-df807f08ad8a].Filename" Value="Document 1 Test" />
<ApplicationItem LayoutPath="Attachments.Package.Attachment[bfd0b74d-2888-49d9-a986-df807f08ad8a].URI" Value="https/.test.pdf" />
<ApplicationItem LayoutPath="Attachments.Package.Attachment[bfd0b74d-2888-49d9-a986-df807f08ad8b].UniqueID" Value="bfd0b74d-2888-49d9-a986-df807f08ad8b" />
<ApplicationItem LayoutPath="Attachments.Package.Attachment[bfd0b74d-2888-49d9-a986-df807f08ad8b].Filename" Value="Document 2 Test" />
<ApplicationItem LayoutPath="Attachments.Package.Attachment[bfd0b74d-2888-49d9-a986-df807f08ad8b].URI" Value="google.com" />
</Application>
The expected result:
<Package>
<Attachment UniqueID="bfd0b74d-2888-49d9-a986-df807f08ad8a"
Filename="Document 1 Test"
URI="https/.test.pdf"/>
<Attachment UniqueID="bfd0b74d-2888-49d9-a986-df807f08ad8b"
Filename="Document 2 Test"
URI="google.com"/>
<Package>
My code:
I've done the grouping by using the id from the square brackets.
<xsl:for-each-group select="ApplicationItem[contains(#LayoutPath,'Attachments.Package.Attachment')]" group-by="substring-before(substring-after(#LayoutPath, 'Attachments.Package.Attachment['), ']')">
<Attachment>
<xsl:for-each select="current-group()">
<xsl:attribute name="UniqueID" select="current-grouping-key()"/>
<xsl:attribute name="Filename" select=".[contains(#LayoutPath,'Filename')]/#Value"/>
<xsl:attribute name="URI" select=".[contains(#LayoutPath,'URI')]/#Value"/>
</xsl:for-each>
<Attachment>
</xsl:for-each-group>
My results:
<Package>
<Attachment UniqueID="bfd0b74d-2888-49d9-a986-df807f08ad8a"
Filename=""
URI="https/.test.pdf"/>
<Attachment UniqueID="bfd0b74d-2888-49d9-a986-df807f08ad8b"
Filename=""
URI="google.com"/>
<Package>
What i need to change in code to use the grouping because for now is not working taking only the last ApplicationItem with the unique #LayoutPath.
I think the problem is with the grouping but don't now how to fix it.
Remove the <xsl:for-each select="current-group()"> and change
<xsl:attribute name="Filename" select=".[contains(#LayoutPath,'Filename')]/#Value"/>
<xsl:attribute name="URI" select=".[contains(#LayoutPath,'URI')]/#Value"/>
to
<xsl:attribute name="Filename" select="current-group()[contains(#LayoutPath,'Filename')]/#Value"/>
<xsl:attribute name="URI" select="current-group()[contains(#LayoutPath,'URI')]/#Value"/>

Url rewriting with "-" symbol for dividing parameters

My current url is: mysite.com/datasheet/100-DE-xmas2016-6
in web.config:
<rule name="myrule">
<match url="^datasheet/([_0-9a-z-]+)-([_0-9a-z-]+)-([_0-9a-z-]+)" />
<action type="Rewrite" url="ajax/datasheet.aspx?shop={R:1}&language={R:2}&product={R:3}" />
</rule>
it will not rewrites to
mysite.com/ajax/datasheet.aspx?shop_id=100&language=DE&product=xmas2016-6
Why???
How to make possible product "xmas2016-6" to work?
The list "mysite.com/datasheet/100-DE-xmas20166" will work. But I really want to use product as "xmas2016-6" (in regular expression set to [_0-9a-z-], but its like ignoring my "-" symbol in product parameter or what?)
This rule will work for you:
<rule name="myrule">
<match url="^datasheet/([_0-9a-z]+)\-([_0-9A-Z]+)\-([_a-z]+[0-9]{4})([0-9]{1})$" />
<action type="Rewrite" url="/ajax/datasheet.aspx?shop={R:1}&language={R:2}&product={R:3}-{R:4}" />
</rule>
Regexp ^datasheet/([_0-9a-z]+)\-([_0-9A-Z]+)\-([_a-z]+[0-9]{4})([0-9]{1})$ is splitting datasheet/100-DE-xmas20166 into four groups:
{R:0} datasheet/100-DE-xmas20166
{R:1} 100
{R:2} DE
{R:3} xmas2016
{R:4} 6

Resources