Skip to content

Commit

Permalink
Initial implemention of XPath parsing / name-prefixing; see #45
Browse files Browse the repository at this point in the history
wendellpiez authored and david-waltermire committed Dec 21, 2020
1 parent eedb0f4 commit b5797ca
Showing 2 changed files with 96 additions and 0 deletions.
34 changes: 34 additions & 0 deletions toolchains/xslt-proto-v04/metapath/parse-metapath-test.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
exclude-result-prefixes="xs math"
version="3.0"
xmlns:m="http://csrc.nist.gov/ns/oscal/metaschema/1.0"
xmlns:mp="http://csrc.nist.gov/ns/oscal/metapath/1.0"
xmlns:p="xpath20">

<xsl:import href="parse-metapath.xsl"/>

<xsl:output indent="yes"/>

<xsl:mode on-no-match="shallow-skip"/>

<!--<xsl:variable name="target-namespace" select="string(/m:METASCHEMA/m:namespace)"/>
<xsl:variable name="declaration-prefix" select="string(/m:METASCHEMA/m:short-name)"/>
-->
<xsl:template match="/">
<xsl:variable name="path">@pink[../link/@href='.']</xsl:variable>
<test>
<path>
<xsl:value-of select="mp:prefixed-path($path)"/>
</path>
<xsl:sequence select="p:parse-XPath($path)"/>
</test>
</xsl:template>



</xsl:stylesheet>
62 changes: 62 additions & 0 deletions toolchains/xslt-proto-v04/metapath/parse-metapath.xsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:math="http://www.w3.org/2005/xpath-functions/math"
xmlns:m="http://csrc.nist.gov/ns/oscal/metaschema/1.0"
exclude-result-prefixes="#all"
version="3.0"
xmlns:mp="http://csrc.nist.gov/ns/oscal/metapath/1.0"

xmlns:p="xpath20">

<xsl:import href="REx/xpath20.xslt"/>

<xsl:output indent="yes"/>

<xsl:mode on-no-match="shallow-skip"/>

<xsl:param name="declaration-prefix" select="(/m:METASCHEMA/m:short-name/string(.),'PRFX')[1]"/>

<xsl:function name="mp:prefixed-path" as="xs:string">
<xsl:param name="expr" as="xs:string"/>


<xsl:variable name="parse.tree" select="p:parse-XPath($expr)"/>
<xsl:value-of>
<xsl:apply-templates select="$parse.tree" mode="prefix-ncnames"/>
</xsl:value-of>
</xsl:function>

<xsl:template match="AxisStep/*[not(ForwardAxis/TOKEN=('@','attribute'))]/NodeTest/NameTest/QName[not(contains(.,':'))]" mode="prefix-ncnames">
<xsl:value-of select="$declaration-prefix[matches(.,'\S')] ! (. || ':')"/>
<xsl:next-match/>
</xsl:template>

<xsl:template match="AxisStep/*/AbbrevForwardStep[not(TOKEN='@')]/NodeTest/NameTest/QName[not(contains(.,':'))]" mode="prefix-ncnames">
<xsl:value-of select="$declaration-prefix[matches(.,'\S')] ! (. || ':')"/>
<xsl:next-match/>
</xsl:template>

<xsl:function name="mp:xpath-eval-okay" as="xs:boolean">
<xsl:param name="expr" as="xs:string"/>
<xsl:variable name="any.place" as="element()"><mp:any/></xsl:variable>
<!-- this filter assumes that a successful parse does not deliver mp:ERROR (hah) -->
<xsl:sequence select="empty(mp:try-xpath-eval($expr,$any.place)/mp:ERROR)"/>
</xsl:function>

<xsl:function name="mp:try-xpath-eval" as="element()">
<xsl:param name="expr" as="xs:string"/>
<xsl:param name="from" as="node()"/>
<xsl:message expand-text="true">expr: { $expr } from: { name($from) }</xsl:message>
<mp:try>
<xsl:try xmlns:err="http://www.w3.org/2005/xqt-errors">
<xsl:evaluate context-item="$from" xpath="$expr"/>
<xsl:catch expand-text="true">
<mp:ERROR code="{ $err:code}">{ $err:description }</mp:ERROR>
</xsl:catch>
</xsl:try>
</mp:try>
</xsl:function>


</xsl:stylesheet>

0 comments on commit b5797ca

Please sign in to comment.