openSUSE:Packaging XML Schemas and Stylesheets
Build Service Tutorial 路 Tips & Tricks 路 Cross Distribution Howto 路 Packaging checks
Desktop menu categories 路 RPM Macros 路 Scriptlets 路 Init scripts 路 How to write good changes
Purpose
This page is intended to define a common set of rules for packaging XML schemas and stylesheets which have a public URI or identifier.
XML Catalogs
Accessing resources as paths can give you some problems:
- Paths are platform dependent (compare /usr/share/xml/ with C:\Program\...)
- Some (older) operating systems does not distinguish between uppercase or lowercase paths.
- Paths can change
XML catalogs solve these problems. They are meant as a "mapping table" between URIs and local paths. With XML catalogs you gain the following benefits:
- Speed: You don't download resources each time you process your XML documents, but are redirected to a local path.
- Exchangeability: it makes exchange between different operating systems much easier as you can rely on general URIs.
- Centralization: with XML catalogs, you have one central place to configure your generic URIs
For example, the official public identifier for DocBook V4.5 is "-//OASIS//DTD DocBook XML V4.5//EN". However, this is an identifier which does not define where the DTD is really stored. To get the real path, query the XML catalog and use the command xmlcatalog:
$ xmlcatalog /etc/xml/catalog "-//OASIS//DTD DocBook XML V4.5//EN" file:/usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd
Whenever a XML document refers to this public identifier, it will receive the local path /usr/share/xml/docbook/schema/dtd/4.5/docbookx.dtd.
Concept
The XML catalog concept on SUSE consists of three catalogs:
- a main catalog, located in /etc/xml/catalog. Normally, you don't touch this.
- subcatalogs, which are placed under the directory /etc/xml/catalog.d/. The subcatalogs are usually named after their package names to distinguish them (PACKAGENAME.xml). This is the place where you add all your identifiers.
- a generated XML catalog /etc/xml/catalog-d.xml which is rewritten during installation, update, and removal. Never touch this catalog!
Normally, any XML tools on Linux query the main catalog, but not any subcatalogs. This is an implementation detail and is different on each Linux distribution鈥攅ven sometimes between different openSUSE releases.
Add XML Catalog Support
Use the following steps to add XML catalog support to your package:
Step 1: Prepare Your XML Catalog
- Create a XML catalog file and name it like your RPM package. For example, if your RPM package is foo, name your catalog file foo.xml.
- Insert the URIs, public identifiers etc. in your catalog. See docbook_5.xml as an example. It's recommended to use a <group> element and add all identifiers as child elements.
Step 2: Create your Spec File
To create a spec file, use the following steps:
- Start with the usual copyright notice:
# # spec file for package foo-schema # # Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed # upon. The license for this file, and modifications and additions to the # file, is the same license as for the pristine package itself (unless the # license for the pristine package is not an Open Source License, in which # case the license is the MIT License). An "Open Source License" is a # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. # Please submit bugfixes or comments via https://bugs.opensuse.org/ #
- Add the minimum set of placeholders:
%define xml_sysconf_dir %{_sysconfdir}/xml %define xml_catalogd_dir %{xml_sysconf_dir}/catalog.d
- Recommended, but optionally, define more placeholders. It makes things easier to change and more consistent. For example, if your package foo comes with a RELAX NG, Schematron, XSD, and/or NVDL schemas, you could define (leave out the things you do not need):
%define foo_dir %{_datadir}/xml/foo %define foo_schema_dir %{foo_dir}/schema %define foo_rng_dir %{foo_schema_dir}/rng %define foo_nvdl_dir %{foo_schema_dir}/nvdl %define foo_sch_dir %{foo_schema_dir}/sch %define foo_xsd_dir %{foo_schema_dir}/xsd %define foo_version 2.0
- In your header, add another source line with the name of your XML catalog file, for example:
Source1: %{name}.xml
- Require at least sgml-skel >= 0.7:
Requires: sgml-skel >= 0.7 Requires(post): sgml-skel >= 0.7 Requires(postun): sgml-skel >= 0.7
- Optionally add a %build section if you need to build your catalog first. See its-schema as an example.
- Install the XML catalog in the %install section:
%install mkdir -p %{buildroot}%{xml_catalogd_dir} # ... cp -vi %{SOURCE1} %{buildroot}%{xml_catalogd_dir}
If you have already Makefile, Shell script etc. this step can be reduced. To install schemas and other files, you need to extend this step (use the placeholders from step 3).
- Add %post and %postun sections:
%post update-xml-catalog %postun update-xml-catalog
- Add the XML catalog as %config in the %files section:
%config %{xml_sysconf_dir}/catalog.d/%{name}.xml
Done!
It's recommended to apply the spec-cleaner command (same package name) to your spec file to improve style and consistency.
Step 3: Build and Test it
- Install your RPM package and query the catalog with xmlcatalog (see above).
- Rebuild the RPM package and reinstall it. Query again the main catalog, there should not be any changes.
- Remove the RPM package. When you query the main catalog, your URIs or identifiers should not be accessible anymore.