I am working on a framework based on a previous authors work and wanted to downgrade the XML to not have XML namespace support, basically because it is not needed and over complicates the end result.
Here is example XML:
<ae:configurations xmlns:ae="http://domain.tld/xml/config/global/envelope" xmlns="http://domain.tld/xml/config/parts/routing">
<ae:configuration context="web">
<routes>
<!-- The last route in case the input URL is just "/". -->
<route name="examples" pattern="^/examples" module="Examples" action="Default">
<route name=".caching" pattern="/caching$" module="Examples" action="Caching" />
<route name=".configuration" pattern="/configuration$" module="Examples" action="Configuration" />
<route name=".exceptions" pattern="/exceptions$" module="Examples" action="Exceptions" />
<route name=".routing" pattern="/routing$" module="Examples" action="Routing" />
<route name=".sessions" pattern="/sessions$" module="Examples" action="Sessions" />
<route name=".database" pattern="/database$" module="Examples" action="Database" />
<route name=".forms" pattern="/forms$" module="Examples" action="Forms" />
<route name=".generator" pattern="/generator$" module="Examples" action="Generator" />
<route name=".templating" pattern="/templating$" module="Examples" action="Templating" />
<route name=".translation" pattern="/translation$" module="Examples" action="Translation" />
</route>
<route name="index" pattern="^/$" module="%chains.default_module%" action="%chains.default_action%" />
</routes>
</ae:configuration>
</ae:configurations>
Which has the following XSD files:
routing.xsd
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:types="http://domain.tld/xml/config/global/types"
xmlns:routing="http://domain.tld/xml/config/parts/routing"
targetNamespace="http://domain.tld/xml/config/global/envelope"
elementFormDefault="qualified"
version="$Id$">
<xs:import namespace="http://domain.tld/xml/config/global/types"
schemaLocation="_types.xsd" />
<xs:import namespace="http://domain.tld/xml/config/parts/routing"
schemaLocation="parts/routing.xsd" />
<xs:redefine schemaLocation="_envelope.xsd">
<xs:complexType name="configuration">
<xs:complexContent>
<xs:extension base="configuration">
<xs:group ref="routing:configuration" />
<xs:attributeGroup ref="types:contexts" />
</xs:extension>
</xs:complexContent>
</xs:complexType>
</xs:redefine>
</xs:schema>
parts/routing.xsd
<xs:schema
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:envelope="http://domain.tld/xml/config/global/envelope"
xmlns:types="http://domain.tld/xml/config/global/types"
xmlns="http://domain.tld/xml/config/parts/routing"
targetNamespace="http://domain.tld/xml/config/parts/routing"
elementFormDefault="qualified"
version="$Id$">
<xs:import namespace="http://domain.tld/xml/config/global/types"
schemaLocation="../_types.xsd" />
<xs:import namespace="http://domain.tld/xml/config/global/envelope"
schemaLocation="../_envelope.xsd" />
<xs:simpleType name="route_name">
<xs:restriction base="xs:string">
<xs:pattern value="[^\+\-]+" />
</xs:restriction>
</xs:simpleType>
<xs:group name="ignores">
<xs:choice>
<xs:element name="ignores" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element name="ignore" type="xs:string"
maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="ignore" type="xs:string"
maxOccurs="unbounded" />
</xs:choice>
</xs:group>
<xs:element name="default">
<xs:complexType>
<xs:simpleContent>
<xs:extension base="xs:string">
<xs:attribute name="for" type="xs:string" use="required" />
</xs:extension>
</xs:simpleContent>
</xs:complexType>
</xs:element>
<xs:group name="defaults">
<xs:choice>
<xs:element name="defaults" minOccurs="0">
<xs:complexType>
<xs:sequence>
<xs:element ref="default"
maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element ref="default"
minOccurs="0" maxOccurs="unbounded" />
</xs:choice>
</xs:group>
<xs:complexType name="callback">
<xs:sequence>
<xs:group ref="envelope:parameters" />
</xs:sequence>
<xs:attribute name="class" type="types:php_class" />
</xs:complexType>
<xs:complexType name="callbacks">
<xs:sequence>
<xs:element name="callback" type="callback" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:group name="callbacks">
<xs:choice>
<xs:element name="callbacks" type="callbacks"
minOccurs="0" />
<xs:element name="callback" type="callback"
minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
</xs:group>
<!-- Routes -->
<xs:complexType name="route">
<xs:sequence minOccurs="0" maxOccurs="unbounded">
<!-- Parameters should be explicitly allowed in routes, but if we include
them in the schema it becomes non-deterministic according to libxml.
They are queried by the internal handler, though. -->
<xs:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded" />
<xs:group ref="ignores" />
<xs:group ref="defaults" />
<xs:group ref="routes" />
<xs:group ref="callbacks" />
</xs:sequence>
<xs:attribute name="name" type="route_name" />
<xs:attribute name="pattern" type="xs:string" use="required" />
<xs:attribute name="imply" type="xs:string" />
<xs:attribute name="cut" type="xs:string" />
<xs:attribute name="stop" type="xs:string" />
<xs:attribute name="source" type="xs:string" />
<xs:attribute name="constraint" type="xs:string" />
<!-- Values to be set on match -->
<xs:attribute name="action" type="xs:string" />
<xs:attribute name="locale" type="xs:string" />
<xs:attribute name="method" type="xs:string" />
<xs:attribute name="module" type="xs:string" />
<xs:attribute name="output_type" type="xs:string" />
</xs:complexType>
<xs:complexType name="routes">
<xs:sequence>
<xs:element name="route" type="route" maxOccurs="unbounded" />
</xs:sequence>
</xs:complexType>
<xs:group name="routes">
<xs:choice>
<xs:element name="routes" type="routes"
minOccurs="0" />
<xs:element name="route" type="route"
minOccurs="0" maxOccurs="unbounded"/>
</xs:choice>
</xs:group>
<xs:group name="configuration">
<xs:sequence>
<xs:any namespace="##other" processContents="lax"
minOccurs="0" maxOccurs="unbounded" />
<xs:group ref="routes" />
</xs:sequence>
</xs:group>
</xs:schema>
With the following XSL file:
routing.xsl
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:routing="http://domain.tld/xml/config/parts/routing"
>
<xsl:output method="xml" version="1.0" encoding="utf-8" indent="yes" />
<xsl:include href="_common.xsl" />
<xsl:variable name="routing" select="'http://domain.tld/xml/config/parts/routing'" />
</xsl:stylesheet>
_common.xsl
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:exslt-common="http://exslt.org/common"
xmlns:saxon="http://icl.com/saxon"
xmlns:envelope="http://framework.youds.com/xml/config/global/envelope"
>
<xsl:variable name="envelope" select="'http://framework.youds.com/xml/config/global/envelope'" />
<!-- callable template for migrating envelope nodes -->
<xsl:template name="_common-migrate-envelope-element">
<!-- param for the target namespace; defaults to 1.0 -->
<xsl:param name="namespace" select="$envelope" />
<!-- attributes to insert, defaults to empty node set -->
<xsl:param name="attributes" select="self::node()[false()]" />
<xsl:call-template name="_common-migrate-element">
<xsl:with-param name="namespace" select="$namespace" />
<xsl:with-param name="attributes" select="$attributes" />
</xsl:call-template>
</xsl:template>
<xsl:template name="_common-migrate-element">
<!-- param for the target namespace; no default -->
<xsl:param name="namespace" />
<!-- attributes to insert, defaults to empty node set -->
<xsl:param name="attributes" select="self::node()[false()]" />
<!-- create an element of the same name -->
<xsl:element name="{local-name()}" namespace="{$namespace}">
<!-- also copy all namespace declarations with a prefix (so only xmlns:foo="...", not plain xmlns="..."), except the one of the current element (otherwise, we'd overwrite the namespace in the <element> above if it's just xmlns etc) -->
<!-- the not(name() = '') part is to ensure that we don't copy xmlns="..." declarations, since that might give very strange results and isn't necessary anyway -->
<!-- the purpose of copying these declarations is to make sure that they remain available as originally declared, which usually is only relevant in cases where element or attribute content refers to the declared prefixes again, think <xs:element type="foo:burp" />. We need that mainly for SOAP, WSDL and stuff like that -->
<xsl:copy-of select="namespace::*[not(name() = '') and not(. = namespace-uri(current()))]" />
<xsl:copy-of select="@*" />
<xsl:copy-of select="exslt-common:node-set($attributes)//@*" />
<xsl:apply-templates />
</xsl:element>
</xsl:template>
<!-- we need to apply templates to sub-elements, just in case someone wrapped a native youds element and processed that with xsl, for example -->
<!-- so we cannot use copy-of here -->
<!-- node() and the copy will mean that everything is copied, even text nodes etc -->
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
There are some other files that may be relevant to its processing, I included those here: https://pastebin.com/aynNT2BT
Apologies for the really generic question I just don't know where to start! So basically the final XML would be <configurations>...</configurations>
and not <ae:configurations>...</ae:configurations>
.
Thanks in advance
Edit: this is work-in-progress at this stage. The idea here was to remove ae:
from the XML declarations, which weren't needed.
So the issue is fixed, it turns out to be a PHP issue that needs addressing as the child <ae:configuration>
etc is allowed to be <configuration>
, the parent node is required to be :ae but that's ok.
Thank you