Home > Net >  How to locate the match node text in a linked XML database using XSLT1?
How to locate the match node text in a linked XML database using XSLT1?

Time:09-26

I know that my XML file format is not good but it is what it is. And I am limited to XSLT-1.

Here is some XSLK script:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msa="http://www.publictalksoftware.co.uk/msa">
    <xsl:output method="html" indent="yes" version="4.01"
      doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
      doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>

    <xsl:variable name="EnglishDB" select="document('MWBData_ENG.XML')"/>
    <xsl:variable name="PunjabiDB" select="document('MWBData_PAN.XML')"/>
    <xsl:template match="/">
        <html>
            <head>
                <meta http-equiv="X-UA-Compatible" content="IE=edge" />
                <title>Terminology List</title>
            </head>
            <body>
                <table>
                    <xsl:apply-templates select ="$EnglishDB/MeetingWorkBook/*/WatchtowerStudyTheme"/>
                    <xsl:apply-templates select ="$PunjabiDB/MeetingWorkBook/*/WatchtowerStudyTheme"/>
                </table>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="WatchtowerStudyTheme">
        <xsl:variable name="week" select="name(..)"/>

        <tr>
            <td>
                <xsl:value-of select="name(..)"/>
            </td>
            <td>
                <xsl:value-of select="."/>
            </td>
        </tr>
    </xsl:template>

</xsl:stylesheet>

Some test XML:

<?xml version="1.0" encoding="UTF-8"?>
<MeetingWorkBook Version="211300">
    <W20191230>
        <WatchtowerStudyTheme>Build Strong Friendships Before the End Comes</WatchtowerStudyTheme>
    </W20191230>
    <W20200106>
        <WatchtowerStudyTheme>How Holy Spirit Helps Us</WatchtowerStudyTheme>
    </W20200106>
</MeetingWorkBook>

The XML "W" nodes do have more children but I am concentrating on just one of them for the moment.

I can assign each XML file to a variable ($EnglishDB and $PunjabiDB) and I can isolate all the English themes and display them in a table.

But what I want to do is locate that English theme in the Punjabi database.

So if we are displaying this node for the English file:

$EnglishDB/MeetingWorkBook/W20191230/WatchtowerStudyTheme

Then I now also want to display:

$PunjabiDB/MeetingWorkBook/W20191230/WatchtowerStudyTheme

But I can't workout how to build a suitable path into the Punabi database.

Ideally I wanted to loop all the topo level "W" elements in the English file and then locate the match "W" element in the Punjabi file so I could simply display the save nodes of interest side by side in two columns.

But can't work the logic out.

CodePudding user response:

Consider this very simplified example:

XML

<anything/>

external.xml

<MeetingWorkBook Version="211300">
    <W20191230>
        <WatchtowerStudyTheme>Build Strong Friendships Before the End Comes</WatchtowerStudyTheme>
    </W20191230>
    <W20200106>
        <WatchtowerStudyTheme>How Holy Spirit Helps Us</WatchtowerStudyTheme>
    </W20200106>
</MeetingWorkBook>

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>

<xsl:param name="external-doc" select="document('external.xml')"/>

<xsl:key name="elem-by-name" match="*" use="name()" />

<xsl:template match="/">
    <xsl:variable name="week">W20200106</xsl:variable>
    <output>
        <!-- switch context to external document -->
        <xsl:for-each select="$external-doc">
            <!-- lookup from external document -->
            <xsl:value-of select="key('elem-by-name', $week)/WatchtowerStudyTheme" />
        </xsl:for-each>
    </output>
</xsl:template>

</xsl:stylesheet>

Result

<?xml version=1.0" encoding="UTF-8"?>
<output>How Holy Spirit Helps Us</output>

CodePudding user response:

I have used local-name() and it seems OK now:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msa="http://www.publictalksoftware.co.uk/msa">
    <xsl:output method="html" indent="yes" version="4.01"
      doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"
      doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN"/>

    <xsl:variable name="EnglishDB" select="document('MWBData_ENG.XML')"/>
    <xsl:variable name="PunjabiDB" select="document('MWBData_PAN.XML')"/>
    <xsl:template match="/">
        <html>
            <head>
                <meta http-equiv="X-UA-Compatible" content="IE=edge" />
                <title>Terminology List</title>
            </head>
            <body>
                <table>
                    <xsl:apply-templates select ="$EnglishDB/MeetingWorkBook/*/WatchtowerStudyTheme"/>
                </table>
            </body>
        </html>
    </xsl:template>
    <xsl:template match="WatchtowerStudyTheme">
        <xsl:variable name="week" select="name(..)"/>

        <tr>
            <td>
                <xsl:value-of select="name(..)"/>
            </td>
            <td>
                <xsl:value-of select="."/>
            </td>
            <td>
                <xsl:value-of select="$PunjabiDB/MeetingWorkBook/*[local-name() = $week]/WatchtowerStudyTheme"/>
            </td>
        </tr>
    </xsl:template>

</xsl:stylesheet>
  • Related