Home > Blockchain >  Why does for-each with if-condition select all instead of specific node's attribute
Why does for-each with if-condition select all instead of specific node's attribute

Time:06-23

I am consolidating information from various XML-files into a single RDF-XML file. I always run out of memory when I try to retrieve a single node as it somehow iterates over many more nodes than intended. The line <xsl:value-of select="$all/relations/rel/@to"/> is the problem here, I guess. What would be the correct way to do it?

This is my xsl script:

<xsl:stylesheet version="3.0">

<xsl:template match="node()|@*">
    <rdf:RDF 
        xmlns:bla="blabla"
        xmlns:owl="http://www.w3.org/2002/07/owl#"
        xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
        xmlns:xml="http://www.w3.org/XML/1998/namespace"
        xmlns:xsd="http://www.w3.org/2001/XMLSchema#"
        xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#">

        
        <xsl:variable name="all" select="collection('./?select=*.xml')"/>

        <xsl:for-each select="$all/sets/singleSet/unit">

            <xsl:variable name="id_unit" select="./@id"/>
            <xsl:variable name="uri_unit">
                <xsl:copy-of select="concat('https://blabla/', $id_unit)" />
            </xsl:variable>

            <NamedIndividual rdf:about="{$uri_unit}">
                
                <bla:identifier rdf:datatype="http://www.w3.org/2001/XMLSchema#string">
                    <xsl:value-of select="./@id"/>
                </bla:identifier>
                
                <!-- THIS PART DOES NOT WORK AS EXPECTED: -->
                <xsl:if test="(($all/relations/rel/@name = 'is_comparable_to') and ($all/relations/rel/@from = $id_unit))">
                    <bla:is_comparable_to rdf:resource="blabla/is_comparable_to">
                        <xsl:value-of select="$all/relations/rel/@to"/>
                    </bla:is_comparable_to>
                </xsl:if>

            </NamedIndividual>
        </xsl:for-each>
        
    </rdf:RDF>
    
</xsl:template>
</xsl:stylesheet>

This is the file where I try to get only the last lines value of 'to':

<relations>
<rel name="has_user" from="28" to="45" dir="one" />
<rel name="is_part_of" from="22" to="90" dir="one" />
<rel name="is_comparable_to" from="55" to="36" dir="one" />
<rel name="is_comparable_to" from="11" to="40" dir="one" />
</relations>

so this is the output I intend to get:

<NamedIndividual rdf:about="https://blabla/11">
    <bla:identifier rdf:datatype="http://www.w3.org/2001/XMLSchema#string">11</bla:identifier>
    <bla:is_comparable_to rdf:resource="blabla/is_comparable_to">40</bla:is_comparable_to>
</NamedIndividual>

CodePudding user response:

You're doing

<xsl:for-each select="$all/sets/singleSet/unit">

and within the body you have several path expressions beginning with $all/relations

Is relations a child element of unit perhaps? At any rate, it seems very odd to be doing a selection starting at $all when you are currently processing elements several levels down from $all. But without seeing what the overall XML looks like, we can't see how to correct it.

CodePudding user response:

It seems to me that within your xsl:for-each you are searching the relations looking for rel elements which connect your current unit to some other unit. If I've understood it correctly, you should use something like this, in place of your xsl:if block:

<xsl:for-each test="$all/relations/rel[@from = $id_unit][@name = 'is_comparable_to']">
    <bla:is_comparable_to rdf:resource="blabla/is_comparable_to">
        <xsl:value-of select="@to"/>
    </bla:is_comparable_to>
</xsl:if>

But also, in your example the RDF/XML syntax for expressing that is_comparable_to property is confused. I think maybe you intend to model the relationship between units (bla:is_comparable_to) as an RDF Object Property? i.e.

<xsl:for-each test="$all/relations/rel[@from = $id_unit][@name = 'is_comparable_to']">
    <bla:is_comparable_to rdf:resource="https://blabla/{@to}"/>
</xsl:if>

... yielding:

<NamedIndividual rdf:about="https://blabla/11">
    <bla:identifier rdf:datatype="http://www.w3.org/2001/XMLSchema#string">11</bla:identifier>
    <bla:is_comparable_to rdf:resource="https://blabla/40"/>
</NamedIndividual>
  • Related