开发者

Is there any way to prevent the display of unmatched xml tags using xslt?

开发者 https://www.devze.com 2022-12-30 00:49 出处:网络
Here is a contrived 开发者_如何转开发example of an xml document.In my real world case, the xml is fairly complex with multiple nested levels.

Here is a contrived 开发者_如何转开发example of an xml document. In my real world case, the xml is fairly complex with multiple nested levels.

<alphabet>
<a>A</a>
<b>B</b>
<c>C</c> 
... and so on
</alphabet>

Using xslt, I want to transform the document so that only the vowels are printed.

In my real world case, we're using empty template match tags to block the display. But that's too verbose for my liking.


I wouldn't allow the "default" or lowest precedence/priority matching template to silently swallow vowels or to do any other meaningful application processing.

It is a good practice that the template for all otherwise unmatched nodes (of a given kind), should produce a good debugging message and, optionally, terminate processing.

If this recommended practice isn't followed, then quite some errors will go silently unnoticed and it would be very difficult to find them and fix in any given fixed period of time.

Here is a solution, which involes only one empty template:

<xsl:stylesheet version="2.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:my="my:my"
 >
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <my:vowels>
   <c>A</c>
   <c>E</c>
   <c>I</c>
   <c>O</c>
   <c>U</c>
 </my:vowels>

 <xsl:template match="node()|@*">
   <xsl:copy>
    <xsl:apply-templates select="node()|@*"/>
   </xsl:copy>
 </xsl:template>

 <xsl:template match="c[not(. = document('')/*/my:vowels/*)]"/>
</xsl:stylesheet>

When this transformation is performed on the following XML document:

<alphabet>
    <c>A</c>
    <c>B</c>
    <c>C</c>
    <c>D</c>
    <c>E</c>
    <c>F</c>
    <c>G</c>
    <c>H</c>
    <c>I</c>
    <c>J</c>
    <c>K</c>
    <c>L</c>
    <c>M</c>
    <c>N</c>
    <c>O</c>
    <c>P</c>
    <c>Q</c>
    <c>R</c>
    <c>S</c>
    <c>T</c>
    <c>U</c>
    <c>V</c>
    <c>W</c>
    <c>X</c>
    <c>Y</c>
    <c>Z</c>
</alphabet>

the wanted result is produced:

<alphabet>
    <c>A</c>
    <c>E</c>
    <c>I</c>
    <c>O</c>
    <c>U</c>
</alphabet>


XSLT has precedence rules for templates with conflicting matches (link to XSLT spec). Therefore, you can have a * template which "swallows" the tags by default and add explicit templates which display or process the vovels.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号