Reputation: 32179
I have a requirement to host a NuGet repository under Apache on Linux. The design is fairly constrained and requires that the Packages feed be stored as a static file. An example of the required output format is here: http://chocolatey.org/api/v2/Packages.
I am attempting to generate this document from the *.nuspec files found inside the *.nupkg archives like so:
#!/bin/bash
#for pkg in nxlog git.install; do
# curl -L http://chocolatey.org/api/v2/package/$pkg -o $pkg.nupkg
#done
unzip "*.nupkg" "*.nuspec"
xsltproc transform.xsl *.nuspec > Packages
rm -f *.nuspec
So far, the incorrect transform xslt looks like this:
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<feed xml:base="http://gallery-host/api/v2/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title type="text">Packages</title>
<id>http://gallery-host/api/v2/Packages</id>
<updated></updated>
<link rel="self" title="Packages" href="Packages" />
<xsl:apply-templates />
</feed>
<xsl:template match="metadata">
<entry>
<id><xsl:value-of select="id"/></id>
<title type="text"><xsl:value-of select="title"/></title>
<summary type="text"><xsl:value-of select="summary"/></summary>
<updated></updated>
<author>
<name><xsl:value-of select="authors"/></name>
</author>
<link rel="edit-media" title="V2FeedPackage">
<xsl:attribute name="href">Packages(Id='<xsl:value-of select="id"/>',Version='<xsl:value-of select="version"/>')/$value</xsl:attribute>
</link>
<link rel="edit" title="V2FeedPackage">
<xsl:attribute name="href">Packages(Id='<xsl:value-of select="id"/>',Version='<xsl:value-of select="version"/>')</xsl:attribute>
</link>
<category term="NuGetGallery.V2FeedPackage" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
<content type="application/zip">
<xsl:attribute name="src">http://chocolatey.org/api/v2/package/<xsl:value-of select="id"/>/<xsl:value-of select="version"/></xsl:attribute>
</content>
<m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<d:Version><xsl:value-of select="version"/></d:Version>
<d:Copyright><xsl:value-of select="copyright"/></d:Copyright>
<!--
<d:Created m:type="Edm.DateTime"></d:Created>
<d:Dependencies></d:Dependencies>
-->
<d:Description><xsl:value-of select="description"/></d:Description>
<!--
<d:DownloadCount m:type="Edm.Int32"></d:DownloadCount>
-->
<d:GalleryDetailsUrl>http://gallery-host/packages/<xsl:value-of select="id"/>/<xsl:value-of select="version"/></d:GalleryDetailsUrl>
<d:IconUrl><xsl:value-of select="iconUrl"/></d:IconUrl>
<!--
<d:IsLatestVersion m:type="Edm.Boolean"></d:IsLatestVersion>
<d:IsAbsoluteLatestVersion m:type="Edm.Boolean"></d:IsAbsoluteLatestVersion>
<d:IsPrerelease m:type="Edm.Boolean"></d:IsPrerelease>
<d:Language m:null="true"></d:Language>
<d:Published m:type="Edm.DateTime"></d:Published>
-->
<d:LicenseUrl><xsl:value-of select="licenseUrl"/></d:LicenseUrl>
<!--
<d:PackageHash></d:PackageHash>
<d:PackageHashAlgorithm></d:PackageHashAlgorithm>
<d:PackageSize m:type="Edm.Int64"></d:PackageSize>
-->
<d:ProjectUrl><xsl:value-of select="projectUrl"/></d:ProjectUrl>
<!--
<d:ProjectSourceUrl m:null="true"></d:ProjectSourceUrl>
<d:PackageSourceUrl m:null="true"></d:PackageSourceUrl>
<d:DocsUrl m:null="true"></d:DocsUrl>
<d:MailingListUrl m:null="true"></d:MailingListUrl>
<d:BugTrackerUrl m:null="true"></d:BugTrackerUrl>
-->
<d:ReportAbuseUrl>http://gallery-host/package/ReportAbuse/<xsl:value-of select="id"/>/<xsl:value-of select="version"/></d:ReportAbuseUrl>
<d:ReleaseNotes><xsl:value-of select="releaseNotes"/></d:ReleaseNotes>
<!--
<d:PackageStatus></d:PackageStatus>
<d:PackageSubmittedStatus m:null="true"></d:PackageSubmittedStatus>
<d:RequireLicenseAcceptance m:type="Edm.Boolean"></d:RequireLicenseAcceptance>
-->
<d:Tags xml:space="preserve"><xsl:value-of select="tags"/></d:Tags>
<d:Title><xsl:value-of select="title"/></d:Title>
<!--
<d:VersionDownloadCount m:type="Edm.Int32"></d:VersionDownloadCount>
-->
</m:properties>
</entry>
</xsl:template>
</xsl:stylesheet>
This results in the output file containing no xml tags (the content is correctly included).
How can I correct my transform.xsl to produce a single root <feed>
element, with multiple child <entry>
elements (so that my output is formatted like http://chocolatey.org/api/v2/Packages)?
UPDATE
Thanks to the pointer from @Martin Honnen, and another from @Frédéric Hamidi (why is it always namespaces that kick you in the nethers, working with xml?), I got a little further with the transform:
<?xml version="1.0" ?>
<xsl:stylesheet
version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes" />
<xsl:template match="/">
<feed>
<xsl:for-each select="p:package/p:metadata" xmlns:p="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<xsl:element name="entry">
<xsl:element name="id"><xsl:value-of select="p:id"/></xsl:element>
<xsl:element name="title">
<xsl:attribute name="type">text</xsl:attribute>
<xsl:value-of select="p:title"/>
</xsl:element>
<xsl:element name="summary">
<xsl:attribute name="type">text</xsl:attribute>
<xsl:value-of select="p:summary"/></xsl:element>
<xsl:element name="author">
<xsl:element name="name"><xsl:value-of select="p:authors"/></xsl:element>
</xsl:element>
<xsl:element name="link">
<xsl:attribute name="rel">edit-media</xsl:attribute>
<xsl:attribute name="title">V2FeedPackage</xsl:attribute>
<xsl:attribute name="href">Packages(Id='<xsl:value-of select="p:id"/>',Version='<xsl:value-of select="p:version"/>')/$value</xsl:attribute>
</xsl:element>
<xsl:element name="link">
<xsl:attribute name="rel">edit</xsl:attribute>
<xsl:attribute name="title">V2FeedPackage</xsl:attribute>
<xsl:attribute name="href">Packages(Id='<xsl:value-of select="p:id"/>',Version='<xsl:value-of select="p:version"/>')</xsl:attribute>
</xsl:element>
<xsl:element name="category">
<xsl:attribute name="term">NuGetGallery.V2FeedPackage</xsl:attribute>
<xsl:attribute name="scheme">http://schemas.microsoft.com/ado/2007/08/dataservices/scheme</xsl:attribute>
</xsl:element>
<xsl:element name="content">
<xsl:attribute name="type">application/zip</xsl:attribute>
<xsl:attribute name="src">http://chocolatey.org/api/v2/package/<xsl:value-of select="p:id"/>/<xsl:value-of select="p:version"/></xsl:attribute>
</xsl:element>
</xsl:element>
<m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<d:Version><xsl:value-of select="p:version"/></d:Version>
<d:Copyright><xsl:value-of select="p:copyright"/></d:Copyright>
<!--
<d:Created m:type="Edm.DateTime"></d:Created>
<d:Dependencies></d:Dependencies>
-->
<d:Description><xsl:value-of select="p:description"/></d:Description>
<!--
<d:DownloadCount m:type="Edm.Int32"></d:DownloadCount>
-->
<d:GalleryDetailsUrl>http://gallery-host/packages/<xsl:value-of select="p:id"/>/<xsl:value-of select="p:version"/></d:GalleryDetailsUrl>
<d:IconUrl><xsl:value-of select="p:iconUrl"/></d:IconUrl>
<!--
<d:IsLatestVersion m:type="Edm.Boolean"></d:IsLatestVersion>
<d:IsAbsoluteLatestVersion m:type="Edm.Boolean"></d:IsAbsoluteLatestVersion>
<d:IsPrerelease m:type="Edm.Boolean"></d:IsPrerelease>
<d:Language m:null="true"></d:Language>
<d:Published m:type="Edm.DateTime"></d:Published>
-->
<d:LicenseUrl><xsl:value-of select="p:licenseUrl"/></d:LicenseUrl>
<!--
<d:PackageHash></d:PackageHash>
<d:PackageHashAlgorithm></d:PackageHashAlgorithm>
<d:PackageSize m:type="Edm.Int64"></d:PackageSize>
-->
<d:ProjectUrl><xsl:value-of select="p:projectUrl"/></d:ProjectUrl>
<!--
<d:ProjectSourceUrl m:null="true"></d:ProjectSourceUrl>
<d:PackageSourceUrl m:null="true"></d:PackageSourceUrl>
<d:DocsUrl m:null="true"></d:DocsUrl>
<d:MailingListUrl m:null="true"></d:MailingListUrl>
<d:BugTrackerUrl m:null="true"></d:BugTrackerUrl>
-->
<d:ReportAbuseUrl>http://gallery-host/package/ReportAbuse/<xsl:value-of select="p:id"/>/<xsl:value-of select="p:version"/></d:ReportAbuseUrl>
<d:ReleaseNotes><xsl:value-of select="p:releaseNotes"/></d:ReleaseNotes>
<!--
<d:PackageStatus></d:PackageStatus>
<d:PackageSubmittedStatus m:null="true"></d:PackageSubmittedStatus>
<d:RequireLicenseAcceptance m:type="Edm.Boolean"></d:RequireLicenseAcceptance>
-->
<d:Tags xml:space="preserve"><xsl:value-of select="p:tags"/></d:Tags>
<d:Title><xsl:value-of select="p:title"/></d:Title>
<!--
<d:VersionDownloadCount m:type="Edm.Int32"></d:VersionDownloadCount>
-->
</m:properties>
</xsl:for-each>
<xsl:for-each select="p:package/p:metadata" xmlns:p="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<xsl:element name="entry">
<xsl:element name="id"><xsl:value-of select="p:id"/></xsl:element>
<xsl:element name="title">
<xsl:attribute name="type">text</xsl:attribute>
<xsl:value-of select="p:title"/>
</xsl:element>
<xsl:element name="summary">
<xsl:attribute name="type">text</xsl:attribute>
<xsl:value-of select="p:summary"/></xsl:element>
<xsl:element name="author">
<xsl:element name="name"><xsl:value-of select="p:authors"/></xsl:element>
</xsl:element>
<xsl:element name="link">
<xsl:attribute name="rel">edit-media</xsl:attribute>
<xsl:attribute name="title">V2FeedPackage</xsl:attribute>
<xsl:attribute name="href">Packages(Id='<xsl:value-of select="p:id"/>',Version='<xsl:value-of select="p:version"/>')/$value</xsl:attribute>
</xsl:element>
<xsl:element name="link">
<xsl:attribute name="rel">edit</xsl:attribute>
<xsl:attribute name="title">V2FeedPackage</xsl:attribute>
<xsl:attribute name="href">Packages(Id='<xsl:value-of select="p:id"/>',Version='<xsl:value-of select="p:version"/>')</xsl:attribute>
</xsl:element>
<xsl:element name="category">
<xsl:attribute name="term">NuGetGallery.V2FeedPackage</xsl:attribute>
<xsl:attribute name="scheme">http://schemas.microsoft.com/ado/2007/08/dataservices/scheme</xsl:attribute>
</xsl:element>
<xsl:element name="content">
<xsl:attribute name="type">application/zip</xsl:attribute>
<xsl:attribute name="src">http://chocolatey.org/api/v2/package/<xsl:value-of select="p:id"/>/<xsl:value-of select="p:version"/></xsl:attribute>
</xsl:element>
</xsl:element>
<m:properties xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">
<d:Version><xsl:value-of select="p:version"/></d:Version>
<d:Copyright><xsl:value-of select="p:copyright"/></d:Copyright>
<!--
<d:Created m:type="Edm.DateTime"></d:Created>
<d:Dependencies></d:Dependencies>
-->
<d:Description><xsl:value-of select="p:description"/></d:Description>
<!--
<d:DownloadCount m:type="Edm.Int32"></d:DownloadCount>
-->
<d:GalleryDetailsUrl>http://gallery-host/packages/<xsl:value-of select="p:id"/>/<xsl:value-of select="p:version"/></d:GalleryDetailsUrl>
<d:IconUrl><xsl:value-of select="p:iconUrl"/></d:IconUrl>
<!--
<d:IsLatestVersion m:type="Edm.Boolean"></d:IsLatestVersion>
<d:IsAbsoluteLatestVersion m:type="Edm.Boolean"></d:IsAbsoluteLatestVersion>
<d:IsPrerelease m:type="Edm.Boolean"></d:IsPrerelease>
<d:Language m:null="true"></d:Language>
<d:Published m:type="Edm.DateTime"></d:Published>
-->
<d:LicenseUrl><xsl:value-of select="p:licenseUrl"/></d:LicenseUrl>
<!--
<d:PackageHash></d:PackageHash>
<d:PackageHashAlgorithm></d:PackageHashAlgorithm>
<d:PackageSize m:type="Edm.Int64"></d:PackageSize>
-->
<d:ProjectUrl><xsl:value-of select="p:projectUrl"/></d:ProjectUrl>
<!--
<d:ProjectSourceUrl m:null="true"></d:ProjectSourceUrl>
<d:PackageSourceUrl m:null="true"></d:PackageSourceUrl>
<d:DocsUrl m:null="true"></d:DocsUrl>
<d:MailingListUrl m:null="true"></d:MailingListUrl>
<d:BugTrackerUrl m:null="true"></d:BugTrackerUrl>
-->
<d:ReportAbuseUrl>http://gallery-host/package/ReportAbuse/<xsl:value-of select="p:id"/>/<xsl:value-of select="p:version"/></d:ReportAbuseUrl>
<d:ReleaseNotes><xsl:value-of select="p:releaseNotes"/></d:ReleaseNotes>
<!--
<d:PackageStatus></d:PackageStatus>
<d:PackageSubmittedStatus m:null="true"></d:PackageSubmittedStatus>
<d:RequireLicenseAcceptance m:type="Edm.Boolean"></d:RequireLicenseAcceptance>
-->
<d:Tags xml:space="preserve"><xsl:value-of select="p:tags"/></d:Tags>
<d:Title><xsl:value-of select="p:title"/></d:Title>
<!--
<d:VersionDownloadCount m:type="Edm.Int32"></d:VersionDownloadCount>
-->
</m:properties>
</xsl:for-each>
</feed>
</xsl:template>
</xsl:stylesheet>
The output still contains too many feed
elements, which I think is due to the way xsltproc handles wildcards/multiple input files (it's running a separate transform for each file, which is actually rather logical). If I could get rid of those, and find a nicer way of handling multiple input namespaces (rather than duplicating the transform code for each namespace), I'd be a happy bunny.
Upvotes: 0
Views: 133
Reputation: 167516
I think you want to replace
<feed xml:base="http://gallery-host/api/v2/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title type="text">Packages</title>
<id>http://gallery-host/api/v2/Packages</id>
<updated></updated>
<link rel="self" title="Packages" href="Packages" />
<xsl:apply-templates />
</feed>
with
<xsl:template match="/">
<feed xml:base="http://gallery-host/api/v2/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom">
<title type="text">Packages</title>
<id>http://gallery-host/api/v2/Packages</id>
<updated></updated>
<link rel="self" title="Packages" href="Packages" />
<xsl:apply-templates />
</feed>
</xsl:template>
But you also need to move all the namespace declarations to the xsl:stylesheet
, i.g.
<xsl:stylesheet xml:base="http://gallery-host/api/v2/" xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices" xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" xmlns="http://www.w3.org/2005/Atom" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">...</xsl:stylesheet>
Upvotes: 1