Goat Karma
Goat Karma

Reputation: 409

XSLT - accessing elements within a collection

I'm attempting to merge multiple XML files within a directory('output') into one single file in a different directory('combine'). The xml files are pretty simple sitemaps:

   <?xml version="1.0" encoding="UTF-8"?>
    <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xmlns:xs="http://www.w3.org/2001/XMLSchema"
            xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
       <url>
          <loc>https://blahblah.com/blah</loc>
          <changefreq>weekly</changefreq>
       </url>
       <url>
          <loc>https://blahblah.com/blah/blah</loc>
          <changefreq>weekly</changefreq>
       </url>
</urlset>

I can successfully use Collection() to retrieve the contents of the files, but I cannot seem to access any elements within those files once they are in the collection.

My XSLT looks like this:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:strip-space elements="*"/>
<xsl:template name="main">
<xsl:variable name="collection" select="collection('output?recurse=yes;select=*.xml')/*"/>
<xsl:variable name="loc" select="distinct-values($collection/urlset/url/loc)"/>
  <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd">
  <xsl:for-each select="$loc">
 <url>
    <loc>  
   <xsl:value-of select="."/>
    </loc>
    </url>  
   </xsl:for-each>
  </urlset>
</xsl:template>
</xsl:stylesheet>

That currently outputs..not very much.

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd"/>

If I change the <xsl:for-each select="$loc"> to be <xsl:for-each select="$collection"> it does output the contents of each file, so I know it can access the collection. However if I try to access any elements directly within the collection files, whether that's via the distinct-values above, or via a variety of different references(see below), it just does not show anything.

I've tried:

<xsl:for-each select="$collection/urlset/url/loc">
 <url>
    <loc>  
   <xsl:value-of select="."/>
    </loc>
    </url>  
   </xsl:for-each>

and

<xsl:for-each select="$collection">
 <url>
    <loc>  
   <xsl:value-of select="urlset/url/loc"/>
    </loc>
    </url>  
   </xsl:for-each>

and

<xsl:for-each select="$loc">
 <url>
    <loc>  
   <xsl:value-of select="($collection/urlset/url[loc=current()])"/>
    </loc>
    </url>  
   </xsl:for-each>

and nothing works, except outputting everything from the collection which at least shows the files can be accessed:

<xsl:for-each select="$collection">
 <url>
    <loc>  
   <xsl:value-of select="."/>
    </loc>
    </url>  
   </xsl:for-each>

If it helps, heres the saxon command I'm using:

java -jar c:\saxon\SaxonHE9-9-1-5J\saxon9he.jar -o:C:\Code\photo.old\xml\sitemap\combine\output.xml -xsl:C:\Code\photo.old\xml\sitemap\combine_s.xslt -it:main

Edit -solved!
Combination of two things:

  1. Martin's response below : you need to have the xpath-default-namespace set to the namespace in the source files: xpath-default-namespace="http://www.sitemaps.org/schemas/sitemap/0.9"
  2. The collection variable did not work with the distinct-values for whatever reason. I needed to define and access the collection directly within the distinct-values command: <xsl:variable name="loc" select="distinct-values(collection('output?strip-space=yes;select=*.xml')/urlset/url/loc)"/>

Upvotes: 0

Views: 702

Answers (1)

Martin Honnen
Martin Honnen

Reputation: 167716

I suppose, if you have the elements in the namespace xmlns="http://www.sitemaps.org/schemas/sitemap/0.9" you want to use xpath-default-namespace="http://www.sitemaps.org/schemas/sitemap/0.9" in the XSLT. Otherwise your paths like urlset/url/loc will select elements of those names in no namespace.

Upvotes: 1

Related Questions