1
votes

I have XML that gets sent off to a third-party vendor as part of a mature feed. The XML is a bit suspect with its usage of namespaces, but I most likely cannot change it at this point since the feed is mature and not to be tinkered with.

I am trying to set up a XSLT template to display the contents of each XML feed as an HTML table. And running into problems.

Below is a simplified version of what I'm trying, selecting just one element. If I can get past whatever I'm missing, I can probably figure out the rest myself.

Partial XML snippet:

<nis:Jobs xmlns:nis="http://schemas.monster.com/Monster/NIS" xmlns="http://schemas.monster.com/Monster" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.monster.com/Monster http://schemas.monster.com/Current/XSD/Job.xsd http://schemas.monster.com/Monster/NIS http://schemas.monster.com/Current/Extensions/NIS/XSD/NISJob.xsd">

    <nis:NISJob>
      <Job jobRefCode="13425840" jobAction="addOrUpdate" jobComplete="true">
          <RecruiterReference>
            <UserName>hj45_32179</UserName>
          </RecruiterReference>
          <CompanyReference>
            <CompanyXCode>xhj45_36079x</CompanyXCode>
            <CompanyName>
              <![CDATA[Clarion Hotel]]>
            </CompanyName>
          </CompanyReference>
          <Channel monsterId="1180"/>
            <JobInformation>
                <JobTitle>
                    <![CDATA[Front Desk Agent, Bartender, Houseperson]]>
                </JobTitle>
                <JobType monsterId="1"/>
                <JobStatus monsterId="4"/>
                <DisableApplyOnline>true</DisableApplyOnline>
                <HideCompanyInfo>true</HideCompanyInfo>
            </JobInformation>
        </Job>
        <nis:AdditionalProducts/>
    </nis:NISJob>
</nis:Jobs>

XLT attempt:

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:nis="http://schemas.monster.com/Monster/NIS" xmlns="http://schemas.monster.com/Monster" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.monster.com/Monster http://schemas.monster.com/Current/XSD/Job.xsd http://schemas.monster.com/Monster/NIS http://schemas.monster.com/Current/Extensions/NIS/XSD/NISJob.xsd"
>

<xsl:template match="/">
  <html>
  <body>
    <h2>Ads in Feed</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>CompanyXCode</th>
      </tr>
      <xsl:for-each select="nis:Jobs/nis:NISJob">
        <tr>
          <td><xsl:value-of select="Job/CompanyReference/CompanyXCode"/></td>
        </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

I have tried this in PHP using the XSLTProcessor, and I've also tried it in W3Schools' Tryit Editor ( http://www.w3schools.com/xsl/tryxslt.asp?xmlfile=cdcatalog&xsltfile=cdcatalog_ex2 ) with no luck.

I'm guessing that there's a problem with the uneven namespace usage in the XML. Any hopes of working around that that anyone knows of?

Thanks in advance!

2

2 Answers

1
votes

Your code works fine for me (Saxon 6.5.5). However, an html element does not need a namespace and not all values are retrieved from the file. So, you need to rethink your usage of namespaces.

EDIT: A second attempt at writing your stylesheet is below. I have used just two namespaces, all elements in your input XML are either in the http://schemas.monster.com/Monster/NIS or http://schemas.monster.com/Monster namespace.

The very first line of your input XML declares a default namespace, which is

xmlns="http://schemas.monster.com/Monster"

Any elements that are not prefixed explicitly, implicitly belong to this namespace. That is why you have to refer to the Job element as mon:Job, for instance.

Finally, use exclude-result-prefixes to prevent XSLT from outputting unwanted namespaces.

Stylesheet

<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:nis="http://schemas.monster.com/Monster/NIS"
xmlns:mon="http://schemas.monster.com/Monster"
exclude-result-prefixes="nis mon">

<xsl:output method="html" indent="yes" />

<xsl:template match="/">
  <html>
  <body>
    <h2>Ads in Feed</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>CompanyXCode</th>
      </tr>
      <xsl:for-each select="nis:Jobs/nis:NISJob">
        <tr>
          <td><xsl:value-of select="mon:Job/mon:CompanyReference/mon:CompanyXCode"/></td>
        </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>

Output

<html>
   <body>
      <h2>Ads in Feed</h2>
      <table border="1">
         <tr bgcolor="#9acd32">
            <th>CompanyXCode</th>
         </tr>
         <tr>
            <td>xhj45_36079x</td>
         </tr>
      </table>
   </body>
</html>
1
votes

The namespace definition and usage in your XSLT is wrong.

Them XML file uses two namespaces:

For Xpath you need to define you own prefixes. That can be the same prefix like in the XML document, or a different one.

<xsl:stylesheet 
  version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:nis="http://schemas.monster.com/Monster/NIS" 
  xmlns:monster="http://schemas.monster.com/Monster"
>

<xsl:template match="/">
  <html>
  <body>
    <h2>Ads in Feed</h2>
    <table border="1">
      <tr bgcolor="#9acd32">
        <th>CompanyXCode</th>
      </tr>
      <xsl:for-each select="nis:Jobs/nis:NISJob">
        <tr>
          <td><xsl:value-of select="monster:Job/monster:CompanyReference/monster:CompanyXCode"/></td>
        </tr>
      </xsl:for-each>
    </table>
  </body>
  </html>
</xsl:template>

</xsl:stylesheet>