首页 文章

删除XSLT转换后的xml中的空元素

提问于
浏览
0

这个问题实际上与另一个问题有关my question . 我有一个示例xml,一个xslt样式表和一个转换后的XML输出文件 . 我想要做的第一件事是我不希望在输出文件中生成没有值的元素 . 第二个是我想从结果文件中的第一个标签中删除那些名称空间声明 . 结果xml文件应该如下所示

<Verification_response>
   <System_Data>
      <STATUSMESSAGE>0</STATUSMESSAGE>
      <TRANSACTIONID>41904</TRANSACTIONID>
   </System_Data>
</Verification_response>

XML输入文件:

<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext">
    <soap:Body>
        <InstantIDResponseEx xmlns="http://webservices.seisint.com/WsIdentity">
            <response>
                <Header>
                    <Status>0</Status>
                    <TransId>41904</TransId>
                    <User></User>
                </Header>
            <Result>
                 <Data/>
            </Result>
        </response>
    </InstantIDResponseEx>
</soap:Body>

XSLT样式表:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:Identity="http://webservices.seisint.com/WsIdentity" 
                xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" 
                xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext" version="1.0">
<xsl:strip-space elements="*"/>


    <!-- ****** MAIN TEMPLATE ******* -->
    <xsl:template match="/">
       <Verification_response>   
              <xsl:apply-templates select="/soap:Envelope/soap:Body/Identity:InstantIDResponseEx/Identity:response"/>
       </Verification_response>
    </xsl:template>

    <xsl:template match = "Identity:response"> 
      <System_Data>
      <xsl:apply-templates select = "Identity:Header" /> 
      </System_Data>
      <Received>
      <xsl:apply-templates select = "Identity:Result" /> 
      </Received>
   </xsl:template>  

    <xsl:template match="Identity:Header">
      <STATUSMESSAGE>
        <xsl:apply-templates select="Identity:Status"/>
      </STATUSMESSAGE>
      <TRANSACTIONID>
        <xsl:apply-templates select="Identity:TransId"/>     
      </TRANSACTIONID>
      <Client>
        <xsl:apply-templates select="Identity:User"/>
      </Client>
    </xsl:template>

    <xsl:template match="Identity:Result">
      <Content>
        <xsl:apply-templates select="Identity:Data"/>
      </Content>
    </xsl:template>

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

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

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

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

</xsl:stylesheet>

转换后的XML:

<Verification_response xmlns:Identity="http://webservices.seisint.com/WsIdentity"
                       xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
                       xmlns:wsse="http://schemas.xmlsoap.org/ws/2002/04/secext">
   <System_Data>
      <STATUSMESSAGE>0</STATUSMESSAGE>
      <TRANSACTIONID>41904</TRANSACTIONID>
      <Client/>
   </System_Data>
   <Received>
      <Content/>
   </Received>
</Verification_response>

我尝试在论坛中的另一个帖子的根节点之前添加以下代码,但它无法正常工作 . 任何人都可以帮我解决这个问题吗?

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

 <xsl:template match=
  "*[not(node())]
  |
   *[not(node()[2])
   and
     node()/self::text()
   and
     not(normalize-space())
     ]
  "/>

1 回答

  • 0

    要删除名称空间声明,请将以下属性添加到 xsl:stylesheet 元素: exclude-result-prefixes="Identity wsse soap" .

    要删除空元素,您需要修改样式表结构 . 这里的问题是你在创建文字结果元素包装器而不检查是否存在任何内容 . 所以你需要有条件地创建它们 - 例如,更改:

    <Received>
        <xsl:apply-templates select = "Identity:Result" /> 
    </Received>
    

    至:

    <xsl:if test="Identity:Result//text()">
        <Received>
            <xsl:apply-templates select = "Identity:Result" /> 
        </Received>
    </xsl:if>
    

    或者将包装器的创建移动到匹配 Identity:Result 的模板,并有条件地将模板应用于:

    <xsl:apply-templates select = "Identity:Result[.//text()]" />
    

    请注意,这将“empty”解释为没有后代文本节点 .

相关问题