0

EDIT: I found a solution that works for me (and it is indeed better to change the RDF syntax, as Conal Tuohy suggested):

<xsl:variable name="all_rels_comparable" select="$all/relations/rel[@name = 'is_comparable_to']"/>
<xsl:for-each select="$all_rels_comparable[@from = $id_lexUnit]">
    <bla:is_comparable_to rdf:resource="blabla/is_comparable_to/{./@to}" />
</xsl:for-each>

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>
  • Please post a [mcve]. --- Hint: you test returns true when there is at least one `rel` that satisfies the condition. That's how the comparison of a node-set to a string is [defined](https://www.w3.org/TR/1999/REC-xpath-19991116/#booleans). If you want to test a specific one, then you need to change your test. I cannot tell you how, because I don't see the entire picture. – michael.hor257k Jun 22 '22 at 15:17

2 Answers2

0

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.

Michael Kay
  • 156,231
  • 11
  • 92
  • 164
0

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>
Conal Tuohy
  • 2,561
  • 1
  • 8
  • 15