简体   繁体   中英

XSLT template to output child elements

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.

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, eg xmlns:tel="http://periapsis.org/tellico/" .
  • The match attribute in your template must refer to just this namespace, ie 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.

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>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM