Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Read an include file using XSL

I want your opinion on what should be my approach to solve this problem. I have a file by the name nav.inc which contains text like for example:

<li class="closed"><a title="x" href="x.html">x</a></li>
<li class="closed"><a title="y" href="y.html">y</a></li>
<li class="closed"><a title="z" href="a.html">z</a></li>

I want to parse this file in xsl so that I can compare each value inside a tag with a variable. The condition is that the extension needs to be .inc, which also means it's not going to be a valid XML.

like image 954
Vinit Avatar asked Sep 25 '26 14:09

Vinit


2 Answers

With XSLT 2.0 you can use the unparsed-text() function to load the nav.inc file and then parse it with xsl:analyze-string to build a variable with a sequence of the href values:

<xsl:variable name="nav-links" as="item()*">
    <xsl:analyze-string select="unparsed-text('nav.inc')" regex="href=&quot;(.*)&quot;">
        <xsl:matching-substring>
            <xsl:sequence select="regex-group(1)"/>
        </xsl:matching-substring>
    </xsl:analyze-string>
</xsl:variable>
like image 81
Mads Hansen Avatar answered Sep 28 '26 05:09

Mads Hansen


The condition is that the extension needs to be .inc, which also means it's not going to be a valid XML

The extension in the file name doesn't mean that the contents cannot be a well-formed XML document.

As the provided example is a completely well-formed XML fragment, you need to arrange that this fragment is wrapped into a single top element.

Then just use the document() function:

$myVar = document('fileName.inc')/*/li[@class = 'closed']/a

The evaluation of this XPath (1.0) expression produces true() if the string value of $myVar is equal to the string value of of an a element that is a child of a li element whose class attribute has string value "closed" and that is a child of the top element of the XML document contained in the file fileName.inc.


If it really cannot be aranged that the file contains a well-formed XML document, use unparsed-text() and xsl:analyze-string.

Here is a complete transformation:

<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vText" select=
      "unparsed-text('file:///c:/temp/delete/fileName.inc')"/>

 <xsl:template match="/">
     <xsl:analyze-string select="$vText" regex="&gt;([^&lt;]*)&lt;/a&gt;" flags="m">
       <xsl:matching-substring>
         <value><xsl:value-of select="regex-group(1)"/></value>
       </xsl:matching-substring>
     </xsl:analyze-string>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on any XML document (not used) it processes the file: c:\temp\delete\fileName.inc which contains the provided text:

<li class="closed"><a title="x" href="x.html">x</a></li>
<li class="closed"><a title="y" href="y.html">y</a></li>
<li class="closed"><a title="z" href="a.html">z</a></li>

and the wanted, correct result is produced:

<value>x</value>
<value>y</value>
<value>z</value>

And here is how to compare a variable to the extracted values:

<xsl:stylesheet version="2.0"   xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output omit-xml-declaration="yes" indent="yes"/>

    <xsl:variable name="vText" select=
      "unparsed-text('file:///c:/temp/delete/fileName.inc')"/>

    <xsl:param name="vSearchValue" select="'y'"/>
 <xsl:template match="/">
   <xsl:variable name="vExtracted" as="element()*">
         <xsl:analyze-string select="$vText" regex="&gt;([^&lt;]*)&lt;/a&gt;" flags="m">
           <xsl:matching-substring>
             <value><xsl:value-of select="regex-group(1)"/></value>
           </xsl:matching-substring>
         </xsl:analyze-string>
     </xsl:variable>

     <xsl:sequence select="$vSearchValue = $vExtracted"/>
 </xsl:template>
</xsl:stylesheet>

When this transformation is applied on any XML document (not used), the wanted, correct result is produced:

true
like image 37
Dimitre Novatchev Avatar answered Sep 28 '26 04:09

Dimitre Novatchev