0

I'm having trouble with XSLT and need help. I replaced my original post with this one. I have an XML file with an empty element that I eventually want to expand using content from a second XML file. I am using the xsltproc (XSLT 1.0) for my processing engine on Ubuntu.

I noticed the Identity Template is not copying the DOCTYPE from the input, if it is supposed to.

I created a simplified test input file and simplified XSLT file. I still cannot get the "genres" XSLT Template to do anything. I changed that template to remove the named element - but it does not do that.

New Input XML -

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE tellico PUBLIC '-//Robby Stephenson/DTD Tellico V11.0//EN' 'http://periapsis.org/tellico/dtd/v11/tellico.dtd'>

<tellico xmlns="http://periapsis.org/tellico/" syntaxVersion="11">
      <collection title="My Videos" type="3">

<entry id="1002">
<title>Midsomer Murders -- Set 25</title>
<id>1002</id>
<comments>Includes bonus material</comments>
<year>2013</year>
<cover>file:///data/www/htdocs/videodb/cache/img/1002.jpg</cover>
<running-time>90</running-time>
<medium>DVD</medium>
<genres></genres>
<set>Yes</set>
<count>3</count>
<location>2</location>
</entry>

</collection>
</tellico>

New XSLT Transform file -

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <!-- the identity template (copies your input verbatim) -->
  <xsl:template match="node() | @*">
    <xsl:copy>
      <xsl:apply-templates select="node() | @*" />
    </xsl:copy>
  </xsl:template>

  <!-- special templates only for things that need them -->
  <xsl:template match="genres"/>


</xsl:stylesheet>

Process command:

xsltproc -o merged.xml --novalid Identity.xslt test-input-merge.xml

I have to use the --novalid option because the periapsis.org site is down at this time.

And the output I get is:

<?xml version="1.0"?>
<tellico xmlns="http://periapsis.org/tellico/" syntaxVersion="11">
      <collection title="My Videos" type="3">

<entry id="1002">
<title>Midsomer Murders -- Set 25</title>
<id>1002</id>
<comments>Includes bonus material</comments>
<year>2013</year>
<cover>file:///data/www/htdocs/videodb/cache/img/1002.jpg</cover>
<running-time>90</running-time>
<medium>DVD</medium>
<genres/>
<set>Yes</set>
<count>3</count>
<location>2</location>
</entry>

</collection>
</tellico>

According to the XSLT transform, and my limited understanding - the "genres" element should have not been included in the output, but it is. This is just a test, for now, to try and figure out how to get the genres template to do something.

I hope this improves on my original post and someone sees what is wrong. Thanks to all for any help you can provide.

wabg278
  • 13
  • 3
  • You wrote: "expand the element". Which element would you like to expand and how? What this "expansion" actually means? – Valdi_Bo May 25 '17 at 15:59
  • My original post had text giving element names that was not accepted, edited the post to place element names in quotes. - sorry, I'm new to this forum. – wabg278 May 25 '17 at 21:34
  • Got it to work by removing the DOCTYPE entry and attributes on the initial "tellico" element from the input XML file. Now I can move on to the processing I really want to happen - add child elements from another XML file to the "genres" element. I will no-doubt need help with that too. THANKS. – wabg278 May 26 '17 at 23:07

2 Answers2

2

I don't know why match="entry[genres]" isn't matching the entry element, but it's wrong anyway. What you need is something like:

<xsl:template match="genres">
  <xsl:copy-of select="document($with)"/>
</xsl:template>
Michael Kay
  • 156,231
  • 11
  • 92
  • 164
  • I changed the xsl:template for genres to match="genres". But it wont fire! Nothing I do makes the genres template do anything. My output duplicates the whole input xml. I'm not concerned with getting the real genre data from another file until I can get the genres template to do something. – wabg278 May 25 '17 at 20:53
  • I've just noticed you said the input XML shown was "partial". Perhaps you left out the important bits, like the namespace declarations? – Michael Kay May 25 '17 at 22:32
1

match="entry[genres]" means that the matched element is entry with genres inside.

So this template processes the whole entry element (not genres).

And what is the result? I made a test using your XML and XSLT and got:

<?xml version="1.0" encoding="ISO-8859-1"?>
    Genre data goes here

So this template outputs just its content, instead of the whole source, and the identity template has no chance to process anything.

Probably you should write match="entry/genres". Or maybe just match="genres" would be enough?

Edit

The real cause why your template did not work was that you forgot about namespace issues, namely the namespace declaration in the root tag.

It causes that:

  • all your tags are in the above mentioned namespace, not in the default (empty) namespace,
  • your template tried to match genres element in the empty namespace.

So you can leave attributes in your source XML, including namespace, but make the following changes in your XSLT:

  • The stylesheet tag must contain declaration of this namespace with some prefix, e.g. xmlns:tel="http://periapsis.org/tellico/".
  • The match attribute in your template must refer to just this namespace, i.e. include the above prefix: <xsl:template match="tel:genres"/>.

As far as the DOCTYPE row is concerned:

Using xsltransform.net I tried to include this row in the source XML but got the following error:

Error on line 1 column 2 of http://periapsis.org/:
  SXXP0003: Error reported by XML parser: The markup declarations
  contained or pointed to by the document type declaration must
  be well-formed.

Probably the reason is inaccessibility or some errors in the referred .dtd file. So I agree with you, that this row should be removed.

Valdi_Bo
  • 30,023
  • 4
  • 23
  • 41
  • Thanks for that. I changed it to just "genres" and then tried "entry/genres" and even made that an empty template expecting the genre elements to be removed and Nothing happens! It appears the genres template is not being seen by the processor. – wabg278 May 25 '17 at 21:21
  • I've just noticed you said the input XML shown was "partial". Perhaps you left out the important bits, like the namespace declarations? – Michael Kay May 25 '17 at 22:31