删除xml中的空元素

时间:2012-03-02 08:44:01

标签: xml xslt xpath

我对xslt转换很新,我需要转换数据集

数据集中的xml如下所示

<?xml version="1.0" standalone="yes"?>
<NewDataSet>
  <Componentstatus>
    <tp_ID>1</tp_ID>
    <StatusName>Not inspected</StatusName>
    <tp_Modified>2012-02-28T10:51:32+01:00</tp_Modified>
    <isacute>1</isacute>
  </Componentstatus>
  <Componentstatus>
    <tp_ID>2</tp_ID>
    <StatusName>Acute</StatusName>
    <tp_Modified>2012-02-28T10:51:40+01:00</tp_Modified>
  </Componentstatus>
  <Componentstatus>
    <tp_ID>3</tp_ID>
    <StatusName>See note</StatusName>
    <tp_Modified>2012-02-28T10:51:45+01:00</tp_Modified>
  </Componentstatus>
  <Componentstatus>
    <tp_ID>4</tp_ID>
    <StatusName>Acceptable</StatusName>
    <tp_Modified>2012-02-28T10:52:36+01:00</tp_Modified>
  </Componentstatus>
  <Componentstatus>
    <tp_ID>5</tp_ID>
    <StatusName>Action recommended</StatusName>
    <tp_Modified>2012-02-28T10:53:07+01:00</tp_Modified>
  </Componentstatus>
</NewDataSet>

xslt

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://ait.com/componentstatus/">
  <xsl:output method="xml" version="4.0" indent="yes" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
  <xsl:template match="//NewDataSet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">z
    <ComponentStatusList>
      <xsl:for-each select="Componentstatus">
        <Status>
          <xsl:attribute name="StatusId">
            <xsl:value-of select="tp_ID" />
          </xsl:attribute>
          <StatusName>
            <xsl:value-of select="StatusName"/>
          </StatusName>
          <Acute>
            <xsl:value-of select="isacute"/>
          </Acute>
        </Status>
      </xsl:for-each>
    </ComponentStatusList>
  </xsl:template>
</xsl:stylesheet>

和genarated xml

<?xml version="1.0" encoding="utf-8"?>z
<ComponentStatusList xmlns="http://ait.com/componentstatus/">
  <Status StatusId="1">
    <StatusName>Not inspected</StatusName>
    <Acute>1</Acute>
  </Status>
  <Status StatusId="2">
    <StatusName>Acute</StatusName>
    <Acute></Acute>
  </Status>
  <Status StatusId="3">
    <StatusName>See note</StatusName>
    <Acute></Acute>
  </Status>
  <Status StatusId="4">
    <StatusName>Acceptable</StatusName>
    <Acute></Acute>
  </Status>
  <Status StatusId="5">
    <StatusName>Action recommended</StatusName>
    <Acute></Acute>
  </Status>
</ComponentStatusList>

正如您所看到的,即使缺少isacute元素,我也会得到一个空的<Acute></Acute>。如何生成xml并删除生成的xml中的元素if if缺少或至少将其设置为<Acute xsi:nil="true" />.

2 个答案:

答案 0 :(得分:1)

一种可能性是在 xsl:if 语句中简单地包含相关的代码位

<xsl:if test="isacute[.]">
    <Acute>    
       <xsl:value-of select="isacute"/>    
   </Acute>   
</xsl:if>

或者,您可以在此处使用模板匹配,如果您希望有多种输出元素的方法,则可以更容易扩展。

在你的情况下,而不是这样做

<Acute>    
    <xsl:value-of select="isacute"/>    
</Acute>   

将其替换为

<xsl:apply-templates select="isacute"/>

然后让模板匹配空和非空案例

<xsl:template match="isacute[.]"> <!-- Output element here --> </xsl:template>
<xsl:template match="isacute"/>

这是完整的XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://ait.com/componentstatus/">
   <xsl:output method="xml" version="4.0" indent="yes" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>

   <xsl:template match="//NewDataSet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
      <ComponentStatusList>
         <xsl:for-each select="Componentstatus">
            <Status>
               <xsl:attribute name="StatusId">
                  <xsl:value-of select="tp_ID"/>
               </xsl:attribute>
               <StatusName>
                  <xsl:value-of select="StatusName"/>
               </StatusName>
               <xsl:apply-templates select="isacute"/>
            </Status>
         </xsl:for-each>
      </ComponentStatusList>
   </xsl:template>

   <xsl:template match="isacute[.]">
      <Acute>
         <xsl:value-of select="."/>
      </Acute>
   </xsl:template>

   <xsl:template match="isacute"/>
</xsl:stylesheet>

当应用于您的示例XML时,输出以下内容

<ComponentStatusList xmlns="http://ait.com/componentstatus/">
   <Status StatusId="1">
      <StatusName>Not inspected</StatusName>
      <Acute>1</Acute>
   </Status>
   <Status StatusId="2">
      <StatusName>Acute</StatusName>
   </Status>
   <Status StatusId="3">
      <StatusName>See note</StatusName>
   </Status>
   <Status StatusId="4">
      <StatusName>Acceptable</StatusName>
   </Status>
   <Status StatusId="5">
      <StatusName>Action recommended</StatusName>
   </Status>
</ComponentStatusList>

答案 1 :(得分:1)

试试这个xslt:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://ait.com/componentstatus/">
  <xsl:output method="xml" version="4.0" indent="yes" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"/>
  <xsl:template match="//NewDataSet" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <ComponentStatusList>
      <xsl:for-each select="Componentstatus">
        <xsl:variable name="isacute" select="isacute"/>
        <Status>
          <xsl:attribute name="StatusId">
            <xsl:value-of select="tp_ID" />
          </xsl:attribute>
          <StatusName>
            <xsl:value-of select="StatusName"/>
          </StatusName>
          <xsl:if test="$isacute!= ''">
          <Acute>
            <xsl:value-of select="isacute"/>
          </Acute>
          </xsl:if>
        </Status>
      </xsl:for-each>
    </ComponentStatusList>
  </xsl:template>
</xsl:stylesheet>