Skip to content

Commit

Permalink
Fix SWRL parsing
Browse files Browse the repository at this point in the history
Addes support for correct xslt transformation
for TOC and SWRL display. The transformation checks
if rdfs:label is defined if not the rules are generically
number as they appear in the XML serialization of the ontology.
  • Loading branch information
Victor Chavez committed Dec 20, 2023
1 parent 4da92b2 commit badb45b
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 16 deletions.
25 changes: 17 additions & 8 deletions src/main/java/widoco/CreateResources.java
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ public static void generateDocumentation(String outFolder, Configuration c, File
if (c.isIncludeOverview()) {
overview = createOverviewSection(folderOut + File.separator + "sections", c, lode.getClassList(),
lode.getPropertyList(), lode.getDataPropList(), lode.getAnnotationPropList(),
lode.getNamedIndividualList(), lode.getRuleList(), languageFile);
lode.getNamedIndividualList(), lode.getRuleList(), lode.getSwrlruleslist(),languageFile);
}
if (c.isIncludeDescription()) {
description = createDescriptionSection(folderOut + File.separator + "sections", c, languageFile);
Expand Down Expand Up @@ -253,7 +253,7 @@ private static String createIntroductionSection(String path, Configuration c,Pro

// the lists passed onto this method are the fixed lists
private static String createOverviewSection(String path, Configuration c, String classesList, String propList,
String dataPropList, String annotationProps, String namedIndividuals, String rules, Properties lang) {
String dataPropList, String annotationProps, String namedIndividuals, String rules, String swrlRules, Properties lang) {
String textToWrite = "";
if ((c.getOverviewPath() != null) && (!"".equals(c.getOverviewPath()))) {
textToWrite = WidocoUtils.readExternalResource(c.getOverviewPath());
Expand All @@ -279,11 +279,16 @@ private static String createOverviewSection(String path, Configuration c, String
textToWrite += ("<h4>" + lang.getProperty(Constants.LANG_NAMED_INDIV) + "</h4>");
textToWrite += (namedIndividuals);
}
if (!"".equals(rules) && rules != null ) {
//only eng support for now
textToWrite += ("<h4> Rules </h4>");
textToWrite += (rules);
}
if (!"".equals(rules) && rules != null ) {
//only eng support for now
textToWrite += ("<h4> Rules </h4>");
textToWrite += (rules);
}
if (!"".equals(swrlRules) && swrlRules != null ) {
//only eng support for now
textToWrite += ("<h4> SWRL Rules </h4>");
textToWrite += (swrlRules);
}
// add the webvowl diagram, if selected
if (c.isCreateWebVowlVisualization()) {
textToWrite += "<iframe align=\"center\" width=\"100%\" height =\"500px\" src=\"webvowl/index.html\"></iframe> ";
Expand Down Expand Up @@ -342,11 +347,15 @@ private static String createCrossReferenceSection(String path, LODEParser lodePa
if (includesNamedIndividual) {
textToWrite += lodeParser.getNamedIndividuals();
}
//since rules are an edge case, if they exist we add them
//since rules and swrl rules are an edge case, if they exist we add them
if(lodeParser.getRuleList()!=null && !lodeParser.getRuleList().isEmpty()){
textToWrite += lodeParser.getRules();
}

if(lodeParser.getSwrlruleslist()!=null && !lodeParser.getSwrlruleslist().isEmpty()){
textToWrite += lodeParser.getSwrlrules();
}

// Add legend (for ontology components actually used).
textToWrite += Constants.getLegend(lang, includesClass, includesProperty,
includesDatatypeProperty, includesAnnotation, includesNamedIndividual);
Expand Down
73 changes: 69 additions & 4 deletions src/main/java/widoco/LODEParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.net.URLDecoder;
import java.util.HashMap;
import java.util.Properties;
import java.util.Objects;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
Expand All @@ -43,7 +44,7 @@
/**
* Class made for parsing and manipulating LODE's html. This class contains most
* of the TemplateGeneratorOLD class
*
*
* @author Daniel Garijo
*/
public class LODEParser {
Expand All @@ -65,12 +66,14 @@ public class LODEParser {
private String namedIndividualList;
private String rules;
private String ruleList;
private String swrlrules;
private String swrlruleslist;
Configuration c;

/**
* Constructor for the LODE parser. The reason for creating this class is to reuse certain parts of
* the generated HTML.
*
*
* @param lodeContent
* text obtained as a response from LODE.
* @param c
Expand Down Expand Up @@ -133,6 +136,42 @@ public String getRuleList() {
return ruleList;
}

public String getSwrlrules() {
return swrlrules;
}

public String getSwrlruleslist() {
return swrlruleslist;
}

/**
* Check if rules are really defined or if the xslt
* generated an empty rule list.
* @return
*/
private boolean rulesDefined(){

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = null;
try {
builder = factory.newDocumentBuilder();
} catch (ParserConfigurationException e) {
throw new RuntimeException(e);
}
// Parse the HTML string as XML
Document doc = null;
try {
doc = builder.parse(new ByteArrayInputStream(ruleList.getBytes()));
} catch (SAXException e) {
throw new RuntimeException(e);
} catch (IOException e) {
throw new RuntimeException(e);
}
// Get the list of <li> elements
NodeList ruleNodes = doc.getElementsByTagName("li");
return ruleNodes.getLength()>0;
}

private void parse(String content, Properties langFile) {

try {
Expand Down Expand Up @@ -185,12 +224,28 @@ private void parse(String content, Properties langFile) {
/*missing: rules!*/
case "rules":
ruleList = (getTermList(html.item(i)));
rules = (nodeToString(html.item(i)));
if (rulesDefined()){
rules = (nodeToString(html.item(i)));
} else {
// No rules defined, false positive
// this happens if owl:NamedIndividuals are defined
// that do not meet the requirements set in
// src/main/resources/lode/extraction.xsl
// <xsl:template name="get.rules">
ruleList="";
rules ="";
}
// rules = rules.replace(
// "<h2>" + langFile.getProperty(Constants.LANG_NAMED_INDIV) + "</h2>",
// "<h3 id=\"rules\" class=\"list\">"
// + langFile.getProperty(Constants.LANG_NAMED_INDIV) + "</h3>");
break;
case "swrlrules":
swrlruleslist = (getTermList(html.item(i)));
swrlrules = (nodeToString(html.item(i)));
swrlrules = swrlrules.replace("<h2>SWRL rules</h2>",
"<h3 id=\"swrlrules\" class=\"list\">SWRL rules</h3>");
break;
}
}
// fix ids
Expand Down Expand Up @@ -221,6 +276,10 @@ private void parse(String content, Properties langFile) {
rules = rules.replace("<a href=\"#namedindividuals\">Named Individual ToC</a>",
"<a href=\"#rules\">Rules ToC</a>");
}
if (!"".equals(swrlruleslist) && swrlruleslist != null) {
swrlruleslist = fixIds(swrlruleslist);
swrlrules = fixIds(swrlrules);
}
logger.info("Parsing Complete!");
} catch (ParserConfigurationException | DOMException ex) {
logger.error("Exception interpreting the resource: " + ex.getMessage());
Expand Down Expand Up @@ -263,6 +322,12 @@ private String nodeToString(Node n) {
// (the second one)
private Node fixAnchor(Node nodeToFix) {
try {
String AttrID = nodeToFix.getAttributes().item(0).getTextContent();
// Do nothing for swrl rules, they do not have
// <a> and <h3>
if (Objects.equals(AttrID, "swrlrules")) {
return nodeToFix;
}
NodeList outerDiv = nodeToFix.getChildNodes();
for (int i = 0; i < outerDiv.getLength(); i++) {
Node currentNode = outerDiv.item(i);
Expand Down Expand Up @@ -307,7 +372,7 @@ private Node fixAnchor(Node nodeToFix) {
/**
* Method to fix the ids generated automatically by LODE with the URIs of the
* classes and properties.
*
*
* @param textToBeFixed
* The input text with the links to be fixed
* @return
Expand Down
Binary file modified src/main/resources/lode.zip
Binary file not shown.
2 changes: 1 addition & 1 deletion src/main/resources/lode/extraction.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -1723,7 +1723,7 @@ http://www.oxygenxml.com/ns/doc/xsl ">
<xsl:if test="exists(/rdf:RDF/(swrl:Imp | rdf:Description[rdf:type[@*:resource = 'http://www.w3.org/2003/11/swrl#Imp']]))">
<li>
<a href="#swrlrules">
<xsl:value-of select="f:getDescriptionLabel('rules')"/>
<xsl:value-of select="f:getDescriptionLabel('swrlrules')"/>
</a>
</li>
</xsl:if>
Expand Down
50 changes: 47 additions & 3 deletions src/main/resources/lode/swrl-module.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,61 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
xmlns:f="http://www.essepuntato.it/xslt/function"
xmlns:dcterms="http://purl.org/dc/terms/"
xmlns="http://www.w3.org/1999/xhtml">



<xsl:template match="rdf:Description" mode="toc">
<li>
<a href="#{generate-id()}">
<xsl:choose>
<xsl:when test="string(rdfs:label)">
<xsl:value-of select="rdfs:label"/>
</xsl:when>
<xsl:otherwise>
<xsl:text>Rule #</xsl:text>
<xsl:value-of select="count(preceding-sibling::rdf:Description[rdf:type[@rdf:resource = 'http://www.w3.org/2003/11/swrl#Imp']]) + 1"/>
</xsl:otherwise>
</xsl:choose>
</a>
</li>
</xsl:template>

<!-- SWRL TOC and SWRL Rule extraction
Copyright (C) 2023, Victor Chavez <[email protected]>
-->
<xsl:template name="get.swrl.toc">
<ul class="hlist">
<xsl:apply-templates select="/rdf:RDF/rdf:Description[rdf:type[@rdf:resource='http://www.w3.org/2003/11/swrl#Imp']]" mode="toc">
<xsl:sort select="rdfs:comment" order="ascending" data-type="text"/>
</xsl:apply-templates>
</ul>
</xsl:template>

<xsl:template match="swrl:Imp | rdf:Description[rdf:type[@rdf:resource = 'http://www.w3.org/2003/11/swrl#Imp']]">
<div id="{generate-id()}" class="entity">
<h3>Rule #<xsl:value-of select="count(preceding-sibling::swrl:Imp | preceding-sibling::rdf:Description[rdf:type[@rdf:resource = 'http://www.w3.org/2003/11/swrl#Imp']]) + 1" /> <xsl:call-template name="get.backlink.to.top" /></h3>
<h3>
<xsl:choose>
<xsl:when test="string(rdfs:label)">
<xsl:value-of select="rdfs:label"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="concat('Rule #', count(preceding-sibling::swrl:Imp | preceding-sibling::rdf:Description[rdf:type[@rdf:resource = 'http://www.w3.org/2003/11/swrl#Imp']]) + 1)"/>
</xsl:otherwise>
</xsl:choose>
<xsl:call-template name="get.backlink.to.top" />
</h3>
<p>
<!-- Add rdfs:comment -->
<xsl:if test="rdfs:comment">
<xsl:value-of select="rdfs:comment" /><br/><br/>
</xsl:if>
<!-- Continue with the existing content -->
<xsl:apply-templates select="swrl:body" />
<xsl:text> -> </xsl:text>
<xsl:apply-templates select="swrl:head" />
</p>
</div>
</xsl:template>

<xsl:template match="swrl:body | swrl:head | swrl:AtomList/rdf:first | rdf:Description[rdf:type[@rdf:resource = 'http://www.w3.org/2003/11/swrl#AtomList']]/rdf:first">
<xsl:apply-templates />
</xsl:template>
Expand Down Expand Up @@ -140,6 +183,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
<xsl:if test="exists(//(swrl:Imp | rdf:Description[rdf:type[@rdf:resource = 'http://www.w3.org/2003/11/swrl#Imp']]))">
<div id="swrlrules">
<h2>SWRL rules</h2>
<xsl:call-template name="get.swrl.toc"/>
<xsl:apply-templates select="//(swrl:Imp | rdf:Description[rdf:type[@rdf:resource = 'http://www.w3.org/2003/11/swrl#Imp']])" />
</div>
</xsl:if>
Expand Down

0 comments on commit badb45b

Please sign in to comment.