如何在 XSL 中删除所有带有条件的空标签

How to remove all empty tag with conditons in XSL

我想删除带有异常的空标签。
我制作了一个 XSL 以删除所有空标签,但有例外。按照下面的 XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:strip-space elements="*"/>
 <xsl:preserve-space elements="cEAN"/ priority="1">
 <xsl:template match="node()|@*">
   <xsl:copy>
      <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
</xsl:template>
<xsl:template match="*[not(@*) and not(*) and (not(text()) or .=-1)]"/>
</xsl:stylesheet>

当 XML 遵循以下规则时,它工作正常,

<?xml version="1.0" encoding="utf-8"?>
  <NFe xmlns:n0="http://mynamespace">
     <cProd>0000000000001</cProd>
     <cEAN> </cEAN>
     <xProd>ARV NAT</xProd>
     <NCM>01000</NCM>
     <CFOP>9999</CFOP>
     </uCom>
 </Nfe>

变换XML:

<?xml version="1.0" encoding="UTF-8"?>
<NFe xmlns:n0="http://mynamespace">
  <cProd>0000000000001</cProd>
  <cEAN />
  <xProd>ARV NAT</xProd>
  <NCM>01000</NCM>
  <CFOP>9999</CFOP>
</NFe> 

但是当 XML 遵循以下规则时,是行不通的。

 <?xml version="1.0" encoding="utf-8"?>
  <NFe xmlns:n0="http://mynamespace">
     <cProd>0000000000001</cProd>
     <cEAN/>
     <xProd>ARV NAT</xProd>
     <NCM>01000</NCM>
     <CFOP>999</CFOP>
     <uCom/>
  </Nfe>

变换XML:

<?xml version="1.0" encoding="UTF-8"?>
<NFe xmlns:n0="http://mynamespace">
   <cProd>0000000000001</cProd>
   <xProd>ARV NAT</xProd>
   <NCM>01000</NCM>
   <CFOP>9999</CFOP>
</NFe>

不保留标签 cEAN,它会删除所有空标签。

有人可以帮助我吗?

首先,您需要更正您的 XMLs 才能有效。我希望你的意思是 <cEAN/></cEAN>,因为我没有看到任何开始标记。 xsl:preserve-space元素中不能有@priority

如果我的假设是正确的,这就是预期的行为。 像下面这样的元素意味着 cEAN 有一个值为 space(</code>).</p> 的文本节点 <pre><code><cEAN> </cEAN>

而且,

<cEAN/>

表示元素 cEAN 中有一个空值(没有文本节点,没有子元素)。 <cEAN/><cEAN></cEAN> 相同。

样式表中的模板:

<xsl:template match="*[not(@*) and not(*) and (not(text()) or .=-1)]"/>

<cEAN/> 匹配,因此在输出中被省略,因为模板不执行任何操作。

要删除除 cEAN 元素之外的所有空元素,您可以使用以下样式表:

<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="*[. = '' and not(self::cEAN)]"/>
</xsl:stylesheet>

如果您的输入符合 XML:

<NFe>
    <cEAN/>
    <CFOP>9999</CFOP>
    <empty/>
</NFe>

输出将是:

<?xml version="1.0" encoding="utf-8"?>
<NFe>
   <cEAN/>
   <CFOP>9999</CFOP>
</NFe>