简体   繁体   English

xslt xml html:如何区分带有或不带有子元素的相同元素?

[英]xslt xml html: how to distinguish the same elements with or without child?

The problem is I want to distinguish same elements name with different situation. 问题是我想区分不同情况下的相同元素名称。 For example: 例如:

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

I want to have elements with text convert into 我想将文本元素转换成

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

and for those elements with child nodes: 对于具有子节点的那些元素:

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

So, the problem is how can I distinguish these two kind of elements in writing the template? 那么,问题是在编写模板时如何区分这两种元素?

一种简单的方法:编写一个带有match="element[normalize-space(text())]"模板,然后编写一个具有match="element[*]模板,第一个模板将element元素与不只是空格的text-node子元素进行匹配;第二个将element元素与child element匹配。

You can use count the descendant elements to see whether or not it has children, eg count(descendant::group)=0 您可以使用count后代元素来查看它是否有子元素,例如count(descendant::group)=0

The XSLT (assuming a root node xml on your input): 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>

Gives the output 给出输出

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

This shorter and simpler transformation: 这个更短,更简单的转换:

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

when applied on the following XML document (the provided XML fragment wrapped into a single top element to be made a well-formed XML document): 当应用于以下XML文档时 (将提供的XML片段包装到单个top元素中,以形成格式良好的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>

produces the wanted, correct result : 产生想要的正确结果

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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