Re: [xsl] Finding an element without a particular attribute?

Subject: Re: [xsl] Finding an element without a particular attribute?
From: "Pieter Masereeuw pieter@xxxxxxxxxxxx" <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 28 Mar 2025 17:18:18 -0000
I recognize your problem. I mitigate it by some preprocessing (in an 
XProc pipeline, but anything else will do).

In the preprocessing, I turn the value of the @key attribute into the 
element's name (supposing it is a NCName) and add a type attribute to 
reflect that it was an array, a map, a string, etc.. For elements that 
don't have a key, I include the name of the parent in the element name 
that I generate. That does not cover everything, but it greatly improves 
readability of the XML.

BTW, in practice, I never use the generated @type attribute, so you may 
want to leave it out.

Below is part of my code.

Pieter

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
 \xA0\xA0\xA0 xmlns:xsl="http://www.w3.org/1999/XSL/Transform";
 \xA0\xA0\xA0 xmlns:xs="http://www.w3.org/2001/XMLSchema";
xmlns:sanoma="http://www.sanoma-learning.com/namespaces/scripting/1";
 \xA0\xA0\xA0 version="3.0">

 \xA0\xA0\xA0 <!-- Stuff left out -->

 \xA0\xA0\xA0 <xsl:function name="sanoma:is-ncname" as="xs:boolean">
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:param name="str" as="xs:string"/>
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:sequence select="$str castable as xs:NCName"></xsl:sequence>
 \xA0\xA0\xA0 </xsl:function>

 \xA0\xA0\xA0 <!-- Replace any json-construct like <string key="">, <map key=""> 
etc. with an XML element named after the value of key, if the value of 
key allows it.
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 This makes the XML coming from JSON, and hence XPath 
expressions, much more readable and simple.
 \xA0\xA0\xA0 -->
 \xA0\xA0\xA0 <xsl:template match="*[@key and sanoma:is-ncname(@key)]">
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:element name="{@key}">
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:attribute name="type" select="name(.)"/>
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:apply-templates select="@* except @key | node()"/>
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 </xsl:element>
 \xA0\xA0\xA0 </xsl:template>

 \xA0\xA0\xA0 <!-- Replace any json-construct without a key attribute with an XML 
element named after the value of key of the parent, if there is a key 
and if that key allows it.
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 This will remove many elements with semantically empty names 
like <map> and <array>. The XPath constructs that mention these elements 
will be more easily understood.
 \xA0\xA0\xA0 -->
 \xA0\xA0\xA0 <xsl:template match="*[not(@key)]">
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:variable name="composed-name" as="xs:string" select="if 
(parent::*[@key and sanoma:is-ncname(@key)]) then name(.) || '.' || 
parent::*/@key else name(.)"/>
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:element name="{$composed-name}">
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:attribute name="type" select="name(.)"/>
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0\xA0 <xsl:apply-templates select="@* | node()"/>
 \xA0\xA0\xA0\xA0\xA0\xA0\xA0 </xsl:element>
 \xA0\xA0\xA0 </xsl:template>
</xsl:stylesheet>

On 3/28/25 17:39, David Carlisle d.p.carlisle@xxxxxxxxx wrote:
>
>
> On Fri, 28 Mar 2025 at 16:30, dvint@xxxxxxxxx 
> <xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> wrote:
>
>     I'm processing content produced with json-to-xml(). So there are a
>     buch
>     of <map> elements. Many have the @key attribute and are easy to
>     match.
>     I'm drawing a blank on how to find map elements without the @key.
>
>     <map key="mime">
>     \xA0 \xA0 <string key="type">array</string>
>     \xA0 \xA0 <array key="items">
>     \xA0 \xA0 \xA0 \xA0<map>
>     \xA0 \xA0 \xA0 \xA0 \xA0 <string key="type">string</string>
>     \xA0 \xA0 \xA0 \xA0</map>
>     \xA0 \xA0 </array
>     \xA0 \xA0 </map>
>     <map key="uri">
>     \xA0 \xA0 <string key="type">string</string>
>     </map>
>     <map key="doctype">
>     \xA0 \xA0 <string key="type">string</string>
>     </map>
>
>
>     Any thoughts? I tried map[@key=''] with no luck.
>
>
> map[not(@key)]
>
>
>     ..dan
>
>
> XSL-List info and archive <http://www.mulberrytech.com/xsl/xsl-list>
> EasyUnsubscribe <http://lists.mulberrytech.com/unsub/xsl-list/3208261> 
> (by email <>)

Current Thread