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:30:06 -0000
Sorry about the hard spaces, introduced somehow when copy-pasting. They only
became apparent when I received my own message.

Computers....

Pieter

Op 28 mrt 2025, 18:18, om 18:18, "Pieter Masereeuw pieter@xxxxxxxxxxxx"
<xsl-list-service@xxxxxxxxxxxxxxxxxxxxxx> schreef:
>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