代码之家  ›  专栏  ›  技术社区  ›  StevenWilkins

是否有任何方法可以防止使用XSLT显示不匹配的XML标记?

  •  2
  • StevenWilkins  · 技术社区  · 14 年前

    下面是一个人为设计的XML文档示例。在我的实际情况中,XML相当复杂,有多个嵌套级别。

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

    使用XSLT,我希望转换文档以便只打印元音。

    在我的现实世界中,我们使用空模板匹配标记来阻止显示。但这对我来说太冗长了。

    2 回复  |  直到 14 年前
        1
  •  1
  •   Dimitre Novatchev    14 年前

    我不允许“默认”或最低优先级/优先级匹配模板无声地吞咽元音或执行任何其他操作。 有意义 应用程序处理 .

    对于所有其他不匹配的节点(给定类型的节点),模板应该生成一个良好的调试消息,并且可以选择终止处理,这是一个很好的实践。

    如果不遵循这一建议的实践,那么相当多的错误会悄悄地被忽略,并且很难在任何给定的固定时间内找到并修复它们。

    这里有一个解决方案,它只调用一个空模板 :

    <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>
    

    在以下XML文档上执行此转换时 :

    <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>
    

    产生了想要的结果 :

    <alphabet>
        <c>A</c>
        <c>E</c>
        <c>I</c>
        <c>O</c>
        <c>U</c>
    </alphabet>
    
        2
  •  0
  •   Lucero    14 年前

    XSLT有 precedence rules for templates with conflicting matches (链接到XSLT规范)。因此,您可以有一个*模板,默认情况下它“吞下”标签,并添加显示或处理Vovels的显式模板。