当一个空的时候使用不同的元素

时间:2014-03-20 16:38:09

标签: xml xslt xslt-1.0

我有一个XML文件,其中包含两个元素中相同的数据。一个元素" HTMLDesc"旨在用于网络,包括HTML字符,如项目符号。另一个" Fulldesc"用于打印目的。当两个元素都包含数据时,我们希望在所有情况下都使用HTML元素。但是,当HTML元素丢失或为空时,我想使用基于print的元素。我知道这是一个IF / ELSE函数,但是当第一个元素为空或缺少时,如何编写XSLT来选择第二个元素?

以下是XML示例:

<dataroot>
<CaseStudies>
<H3>New Patient</H3>
<Fulldesc>Office or other outpatient visit.</Fulldesc>
<HTMLdesc><b>Office or other outpatient visit</b></HTMLdesc>
</CaseStudies>

<CaseStudies>
<H3>Old Patient</H3>
<Fulldesc>Office or other outpatient visit.</Fulldesc>
</CaseStudies>

<CaseStudies>
<H3>Young Patient</H3>
<Fulldesc>Office or other outpatient visit.</Fulldesc>
<HTMLdesc><b>Office or other outpatient visit</b></HTMLdesc>
</CaseStudies>

<CaseStudies>
<category>1</category>
<GroupNo>2</GroupNo>
<H3>Female Patient</H3>
<Fulldesc>Office or other outpatient visit.</Fulldesc>
<HTMLdesc />
</CaseStudies>
</dataroot>

这是基本的XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:strip-space elements="*"/>

<xsl:output method="xml"/>
<xsl:template match="/">

<dataroot>
<xsl:apply-templates select="dataroot"/>
</dataroot>
</xsl:template>

<xsl:template match="CaseStudies">
<CaseStudies>
<xsl:apply-templates select="H3"/>
<xsl:apply-templates select="HTMLdesc"/>
</CaseStudies>
</xsl:template>

<H3><xsl:value-of select="."/></H3></xsl:template>

<xsl:template match="HTMLdesc">
<HTMLdesc><xsl:value-of select="."/></HTMLdesc></xsl:template>

</xsl:stylesheet>

3 个答案:

答案 0 :(得分:1)

您可以在xsl:choose元素内决定是否在apply-templatesHTMLdesc元素上执行Fulldesc

如果Fulldesc仅包含空白字符,此解决方案还会选择HTMLdesc元素。

请注意,除了在给定条件下选择某些节点外,您的确没有太大变化。在这种情况下,始终建议以身份转换开始(而不是像在样式表中那样再次键入所有元素)

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

并根据需要添加其他模板。

<强>样式表

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>

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

  <xsl:template match="category|GroupNo"/>

  <xsl:template match="CaseStudies">
      <xsl:copy>
      <xsl:apply-templates select="@*|comment()|processing-instruction()|H3"/>
          <xsl:choose>
              <xsl:when test="normalize-space(HTMLdesc) = ''">
                  <xsl:apply-templates select="Fulldesc"/>
              </xsl:when>
              <xsl:otherwise>
                  <xsl:apply-templates select="HTMLdesc"/>
              </xsl:otherwise>
          </xsl:choose>
      </xsl:copy>
  </xsl:template>

</xsl:stylesheet>

<强>输出

<?xml version="1.0" encoding="utf-8"?>
<dataroot>
   <CaseStudies>
      <H3>New Patient</H3>
      <HTMLdesc>
         <b>Office or other outpatient visit</b>
      </HTMLdesc>
   </CaseStudies>
   <CaseStudies>
      <H3>Old Patient</H3>
      <Fulldesc>Office or other outpatient visit.</Fulldesc>
   </CaseStudies>
   <CaseStudies>
      <H3>Young Patient</H3>
      <HTMLdesc>
         <b>Office or other outpatient visit</b>
      </HTMLdesc>
   </CaseStudies>
   <CaseStudies>
      <H3>Female Patient</H3>
      <Fulldesc>Office or other outpatient visit.</Fulldesc>
   </CaseStudies>
</dataroot>

答案 1 :(得分:1)

此处的其他选项与其他两个答案类似,但并不需要xsl:choose或多个xsl:apply-templates

它基本上将模板应用于:

Fulldesc如果HTMLdesc为空或不存在

HTMLdesc如果不为空

先找到它。

XML输入

<dataroot>
    <CaseStudies>
        <H3>New Patient</H3>
        <Fulldesc>Office or other outpatient visit.</Fulldesc>
        <HTMLdesc><b>Office or other outpatient visit</b></HTMLdesc>
    </CaseStudies>

    <CaseStudies>
        <H3>Old Patient</H3>
        <Fulldesc>Office or other outpatient visit.</Fulldesc>
    </CaseStudies>

    <CaseStudies>
        <H3>Young Patient</H3>
        <Fulldesc>Office or other outpatient visit.</Fulldesc>
        <HTMLdesc><b>Office or other outpatient visit</b></HTMLdesc>
    </CaseStudies>

    <CaseStudies>
        <category>1</category>
        <GroupNo>2</GroupNo>
        <H3>Female Patient</H3>
        <Fulldesc>Office or other outpatient visit.</Fulldesc>
        <HTMLdesc />
    </CaseStudies>
</dataroot>

XSLT 1.0

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="CaseStudies">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()[not(self::Fulldesc) and not(self::HTMLdesc)]|
                (Fulldesc[not(string(../HTMLdesc))]|HTMLdesc[string()])[1]"/>
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet>

XML输出

<dataroot>
   <CaseStudies>
      <H3>New Patient</H3>
      <HTMLdesc>
         <b>Office or other outpatient visit</b>
      </HTMLdesc>
   </CaseStudies>
   <CaseStudies>
      <H3>Old Patient</H3>
      <Fulldesc>Office or other outpatient visit.</Fulldesc>
   </CaseStudies>
   <CaseStudies>
      <H3>Young Patient</H3>
      <HTMLdesc>
         <b>Office or other outpatient visit</b>
      </HTMLdesc>
   </CaseStudies>
   <CaseStudies>
      <category>1</category>
      <GroupNo>2</GroupNo>
      <H3>Female Patient</H3>
      <Fulldesc>Office or other outpatient visit.</Fulldesc>
   </CaseStudies>
</dataroot>

答案 2 :(得分:0)

您可以根据HTMLdesc的内容选择FulldescHTMLdesc模板:

<CaseStudies>
    <xsl:apply-templates select="H3"/>
    <xsl:apply-templates select="HTMLdesc[string()]"/>
    <xsl:apply-templates select="Fulldesc[../HTMLdesc[not(string())] or not(../HTMLdesc)]"/>
</CaseStudies>

第二个apply-templates只有在HTMLdesc模板不为空时才会选择它。

如果Fulldesc兄弟是空的或不存在,第三个将选择HTMLdesc模板(您必须添加到样式表中)。