【问题标题】:xslt xml html: how to distinguish the same elements with or without child?xslt xml html:如何区分有无子元素的相同元素?
【发布时间】:2012-09-11 15:57:57
【问题描述】:

问题是我想区分不同情况下的相同元素名称。例如:

<element>Hello StackOverFlow</element>
<element>
  <group>
     <ge>hello g1</ge>
     <ge>hello g2</ge>
  </group>
  <group>
     <ge>hello g3</ge>
     <ge>hello g4</ge>
  </group>
</element>

我想让带有文本的元素转换成

<div class="text_element">Hello StackOverFlow</div>

对于那些有子节点的元素:

<div class="element">
  <ul class="group">
     <li>hello g1</li>
     <li>hello g2</li>
  </ul>
  <ul class="group">
     <li>hello g3</li>
     <li>hello g4</li>
  </ul>
</div>

那么,问题是在编写模板时如何区分这两种元素呢?

【问题讨论】:

    标签: html xml xslt


    【解决方案1】:

    一种简单的方法:用match="element[normalize-space(text())]" 编写一个模板,用match="element[*] 编写一个模板。第一个匹配element 元素与文本节点子节点,这些子节点不仅仅是空格;第二个将 element 元素与子元素匹配。

    【讨论】:

    • 你真傻,@C。 M. Sperberg-McQueen,您只提供了解决方案的基本要素。您没有为他编写整个样式表。那样你的答案永远不会得到批准!
    【解决方案2】:

    您可以使用对后代元素进行计数来查看它是否有子元素,例如count(descendant::group)=0

    XSLT(假设您的输入中有一个根节点 xml):

    <xsl:stylesheet version="1.1" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="html" version="1.0" indent="yes"/>
    
        <xsl:template match="/xml">
            <xsl:apply-templates select="element"/>
        </xsl:template>
    
        <!-- No children -->
        <xsl:template match="element[count(descendant::group)=0]">
            <div class="text_element">
                <xsl:value-of select="text()"/>
            </div>
        </xsl:template>
    
        <!-- With children -->
        <xsl:template match="element[count(descendant::group)&gt;0]">
            <div class="element">
                <xsl:apply-templates select="group"/>
            </div>
        </xsl:template>
    
        <xsl:template match="group">
            <ul class="group">
                <xsl:apply-templates select="ge"/>
            </ul>
        </xsl:template>
    
        <xsl:template match="ge">
            <li>
                <xsl:value-of select="text()"/>
            </li>
        </xsl:template>
    
    </xsl:stylesheet>
    

    给出输出

    <div class="text_element">Hello StackOverFlow</div>
    <div class="element">
      <ul class="group">
        <li>hello g1</li>
        <li>hello g2</li>
      </ul>
      <ul class="group">
        <li>hello g3</li>
        <li>hello g4</li>
      </ul>
    </div>
    

    【讨论】:

    • 虽然没有错,但就简单性、可读性、效率和 XSLT 的精神而言,element[*] 远优于 element[count(descendant::group)&amp;gt;0]
    • @SeanB.Durkin 谢谢 - 是的,我说得很明确。不太确定 OP 的真正“过滤器”是什么。
    • 这是我想要的确切答案。谢谢。
    【解决方案3】:

    这个更短更简单的转换:

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
     <xsl:output omit-xml-declaration="yes" indent="yes"/>
     <xsl:strip-space elements="*"/>
    
     <xsl:template match="element[not(*)]">
       <div class="text_element"><xsl:apply-templates/></div>
     </xsl:template>
    
     <xsl:template match="element">
      <div class="element">
        <xsl:apply-templates/>
      </div>
     </xsl:template>
    
     <xsl:template match="group">
        <ul class="group">
          <xsl:apply-templates/>
        </ul>
     </xsl:template>
    
     <xsl:template match="ge">
      <li><xsl:apply-templates/></li>
     </xsl:template>
    </xsl:stylesheet>
    

    应用于以下 XML 文档时(将提供的 XML 片段包装到单个顶部元素中以形成格式良好的 XML 文档):

    <t>
        <element>Hello StackOverFlow</element>
        <element>
            <group>
                <ge>hello g1</ge>
                <ge>hello g2</ge>
            </group>
            <group>
                <ge>hello g3</ge>
                <ge>hello g4</ge>
            </group>
        </element>
    </t>
    

    产生想要的正确结果

    <div class="text_element">Hello StackOverFlow</div>
    <div class="element">
       <ul class="group">
          <li>hello g1</li>
          <li>hello g2</li>
       </ul>
       <ul class="group">
          <li>hello g3</li>
          <li>hello g4</li>
       </ul>
    </div>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-03
      • 1970-01-01
      • 2022-07-07
      • 2019-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-30
      相关资源
      最近更新 更多