如果不存在则创建空元素

时间:2009-10-14 09:56:12

标签: xslt

非常感谢您给我回复和帮助。我的问题是在我的xml文件中,某些xml集中缺少某些元素,而其他一些元素存在。因此,如果这些元素不存在,我想只创建值为0的元素。之前我从众所周知的顾问那里得到了答案,我已经实现但没有得到所需的输出可能是我做错了实现。 PLS。帮我。我希望在转换xml文件时添加像SalMin,SalMax,SalT​​ype和SalCurrency这样的新元素。下面是xml文件和xslt文件。

<Jobs> 
  <Job> 
    <Job_ID>80000000</Job_ID>  
    <PositionID>60000002</PositionID>  
    <Title>Development Manager - Investment Banking - Equities Business</Title>  
    <Summary>An experienced Development Manager with previous experience leading a small to mid-size team of developers in a Java/J2EE environment. A hands on role, you will be expected to manage and mentor a team of developers working on a mix of greenfield and maintenance projects.&#160;&#160; My client, a well known investment bank, requires an experienced Development Manager to join their core technology team. This t</Summary>  
    <DateActive>10/6/2009</DateActive>  
    <DateExpire>11/5/2009</DateExpire>  
    <DateUpdated>10/6/2009</DateUpdated>  
    <Country>Country</Country>  
    <State>state</State>  
    <City>city</City>  
    <PostalCode>2000</PostalCode>  
    <CompanyName>Ambition Technology</CompanyName>  
    <BuilderFields />  
    <DisplayOptions />  
    <AddressType>6</AddressType>  
  </Job> 
  <Job> 
    <Job_ID>83790557</Job_ID>  
    <PositionID>61220512</PositionID>  
    <Title>SQL/VB Analyst Programmers With Strong Client Facing Skills $60 - $80K</Title>  
    <Summary>Excellent Location New Technologies Career Potential My client is a fast paced  IT company in Consultancy based in Inner West of Sydney. My client is experiencing a large amount of growth due to new exciting projects which they have won due to their impressive reputation and quality of work. Due to the large amount of growth my client is experiencing they are looking to take on&#160;3 Analyst/Programmer</Summary>  
    <DateActive>10/5/2009</DateActive>  
    <DateExpire>11/4/2009</DateExpire>  
    <DateUpdated>10/5/2009</DateUpdated>  
    <Country>Australia</Country>  
    <State>NSW</State>  
    <City>Sydney</City>  
    <PostalCode>2000</PostalCode>  
    <CompanyName>Skill Quest</CompanyName>  
    <SalMin>30000</SalMin>  
    <SalMax>70000</SalMax>  
    <SalType>Per Year</SalType>  
    <SalCurrency>AUD</SalCurrency>  
    <BuilderFields />  
    <DisplayOptions />  
    <AddressType>6</AddressType>  
  </Job> 

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
  <xsl:output method="xml" indent="yes" encoding="utf-8"
  omit-xml-declaration="no" />
  <xsl:template match="/">
    <Monster>
      <xsl:for-each select="Monster/Jobs">
        <Jobs>

          <!--<Found>
            <xsl:value-of select="@Found" />
          </Found>
          <Returned>
            <xsl:value-of select="@Returned" />
          </Returned>-->
          <xsl:for-each select="Job">
            <Job>
            <Job_ID>
              <xsl:value-of select="@ID" />
            </Job_ID>
            <PositionID>
              <xsl:value-of select="@PositionID" />
            </PositionID>
            <xsl:for-each select="Title">
              <Title>
                <xsl:apply-templates/>
              </Title>
            </xsl:for-each >
            <xsl:for-each select="Summary">
              <Summary>
                <xsl:apply-templates/>
              </Summary>
            </xsl:for-each >
            <xsl:for-each select="DateActive">
              <DateActive>
                <xsl:apply-templates/>
              </DateActive>
            </xsl:for-each >
            <xsl:for-each select="DateExpires">
              <DateExpire>
                <xsl:apply-templates/>
              </DateExpire>
            </xsl:for-each >
            <xsl:for-each select="DateUpdated">
              <DateUpdated>
                <xsl:apply-templates/>
              </DateUpdated>
            </xsl:for-each >
            <xsl:for-each select="Location/Country">
              <Country>
                <xsl:apply-templates/>
              </Country>
            </xsl:for-each >
            <xsl:for-each select="Location/State">
              <State>
                <xsl:apply-templates/>
              </State>
            </xsl:for-each>
            <xsl:for-each select="Location/City">
              <City>
                <xsl:apply-templates/>
              </City>
            </xsl:for-each>
            <xsl:for-each select="Location/PostalCode">
              <PostalCode>
                <xsl:apply-templates/>
              </PostalCode>
            </xsl:for-each>
            <xsl:for-each select="CompanyName">
              <CompanyName>
                <xsl:apply-templates/>
              </CompanyName>
            </xsl:for-each>

  <xsl:for-each select="Salary/Min">             
                <SalMin>
                  <xsl:value-of select="@Value" />
                </SalMin>                          
            </xsl:for-each >
            <xsl:for-each select="Salary/Max">
              <SalMax>
                <xsl:value-of select="@Value" />
              </SalMax>
              </xsl:for-each >
            <xsl:for-each select="Salary/Type">
              <SalType>
                <xsl:apply-templates/>
              </SalType>
            </xsl:for-each >
            <xsl:for-each select="Salary/Currency">
              <SalCurrency>
                <xsl:apply-templates/>
              </SalCurrency>
            </xsl:for-each >
            <xsl:for-each select="BuilderFields">
              <BuilderFields>
                <xsl:apply-templates/>
              </BuilderFields>
            </xsl:for-each >
            <xsl:for-each select="DisplayOptions">
              <DisplayOptions>
                <xsl:apply-templates/>
              </DisplayOptions>
            </xsl:for-each >
            <xsl:for-each select="AddressType">
              <AddressType>
                <xsl:apply-templates/>
              </AddressType>
            </xsl:for-each >
              <xsl:call-template name="ApplyTemplatesOrCreate">
                <xsl:with-param name="elemName" select="'SalMin'" />
                <xsl:with-param name="elemDefault" select="'0'" />
              </xsl:call-template>
            </Job>
            <!--Closing-->
          </xsl:for-each >
        </Jobs >
      </xsl:for-each >
    </Monster>
  </xsl:template>




  <xsl:template name="ApplyTemplatesOrCreate">
    <xsl:param name="elemName" select="'SalMin'" />
    <xsl:param name="elemDefault" select="'0'" />

    <xsl:variable name="elem" select="*[name() = $elemName]" />

    <xsl:choose>
      <xsl:when test="$elem">
        <xsl:apply-templates select="$elem" />
      </xsl:when>
      <xsl:otherwise>
        <xsl:if test="$elemName != ''">
          <xsl:element name="{$elemName}">
            <xsl:value-of select="$elemDefault" />
          </xsl:element>
        </xsl:if>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet >

PLS。给我一个解决方案,早些时候Tomalak先生帮助了我很多,甚至我告诉他我将通过实施他的建议代码得到一个解决方案,但我做错了。

1 个答案:

答案 0 :(得分:5)

由于您之前没有发布过XSL,我们无法确定示例XML实际上是样式表的输出而不是输入。修复这些必需元素的最快最脏的方法是添加一个输入元素是否存在的检查:

        <xsl:for-each select="Salary/Max">
          <SalMax>
            <xsl:value-of select="@Value" />
          </SalMax>
        </xsl:for-each >
        <xsl:if test="not(Salary/Max/@Value)">
          <SalMax>0</SalMax>
        </xsl:if>

更好的是输出所需的元素,然后在里面进行检查:

      <SalMax>
        <xsl:value-of select="Salary/Max/@Value" />
        <xsl:if test="not(Salary/Max/@Value)">0</xsl:if>
      </SalMax>

      <SalType>
        <xsl:apply-templates select="Salary/Type" />
        <xsl:if test="not(Salary/Type)">NO_TYPE</xsl:if>
      </SalType>

你可以写一个模板来调用,类似于Tomalak的,所以你不必复制xpath表达式或逻辑:

    <SalType>
        <xsl:call-template name="ApplyTemplatesOrDefault">
            <xsl:with-param name="elem" select="Salary/Type"/>
            <xsl:with-param name="default">NO_TYPE</xsl:with-param>
        </xsl:call-template>
    </SalType>

...

    <xsl:template name="ApplyTemplatesOrDefault">
        <xsl:param name="elem" />
        <xsl:param name="default" select="0"/>

        <xsl:choose>
            <xsl:when test="$elem">
                <xsl:apply-templates select="$elem" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$default" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>