XSL - 删除空标记并保留空格

时间:2017-12-14 21:18:37

标签: xml xslt

我需要删除空节点,但保留带有空格的节点作为特定属性的值," DELETE"。我对XSL并不熟悉......如何删除空值,但保留空间值?

这仅适用于具有动作" DELETE"的节点。例如,当操作为" DELETE"时,无论其他节点名称是什么(因为它们将更改),都应删除空值子项。如果这是不可能的,我将解决从整个XML文件中删除空值的问题,该文件的代码正在工作并列在下面。但是它不保留空格,不仅仅是属性" DELETE"。以下示例。

<?xml version="1.0" encoding="utf-8"?>
<test xmlns:n0="http://mynamespace">
 <Value Action="DELETE">
    <Example1> </Example1>
    <Test2 />
    <Example3></Example3>
 </Value>
 <Value Action="UPDATE">
   <space> </space>
    <null />
    <null2></null2>
 </Value>
</test>

预期结果:

<?xml version="1.0" encoding="utf-8"?>
<test xmlns:n0="http://mynamespace">
   <Value Action="DELETE">
     <Example1> </Example1>
   </Value>
   <Value Action="UPDATE">
     <space> </space>
     <null />
     <null2></null2>
   </Value>
</test>

删除所有空:

<?xml version="1.0" encoding="UTF-8"?>

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

    <xsl:template match="*">
    <xsl:if test=". != '' or ./@* != ''">
        <xsl:element name="{local-name()}">
            <xsl:apply-templates select="@* | node()" />
        </xsl:element>
    </xsl:if>
    </xsl:template>

   <xsl:template match="@*">
        <xsl:attribute name="{local-name()}">
            <xsl:value-of select="." />
        </xsl:attribute>
   </xsl:template>
       <xsl:template match="text() | comment() | processing-instruction()">
       <xsl:copy />
    </xsl:template>
</xsl:stylesheet>

2 个答案:

答案 0 :(得分:1)

你需要:

  1. 身份模板以复制所有输入。

  2. 匹配符合以下条件的每个节点的模板:

    • 它包含在 Value 节点中, Action 属性设置为 DELETE
    • 其名称包含 null

    忽略此类节点。

    这是一个比单个模板更通用,更简洁的解决方案 对于每个节点名称( null null2 ,...)。

  3. 可选地,模板“阻塞”仅包含空格的文本节点 一个换行符字符。原因是阻止换行文本节点 你的标签之间,但“通过”,例如space标记中包含的空格。

  4. 所以整个脚本可能如下所示:

    <?xml version="1.0" encoding="UTF-8" ?>
    <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
      <xsl:output method="xml" encoding="UTF-8" indent="yes" />
    
      <xsl:template match="Value[@Action = 'DELETE']/*[contains(name(), 'null')]"/>
    
      <xsl:template match="text()[not(normalize-space())][contains(.,'&#xA;')]"/>
    
      <xsl:template match="@*|node()">
        <xsl:copy><xsl:apply-templates select="@*|node()"/></xsl:copy>
      </xsl:template>
    </xsl:transform>
    

答案 1 :(得分:0)

复制所有节点并匹配下一个模板中的避免节点,请参阅下面的XSL(已编辑):

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">       
    <xsl:output method="xml" encoding="utf-8" indent="no" omit-xml-declaration="yes"/>
    <!--copy all nodes--> 
    <xsl:template match="@*|node()">            
        <xsl:copy>                
            <xsl:apply-templates select="@*|node()" />           
        </xsl:copy>        
    </xsl:template>
    <!--preventing spaces between nodes-->
    <xsl:template match="text()">
        <xsl:value-of select="normalize-space()" />
    </xsl:template>    
    <!--match all elements which contain null for DELETE with doing nothing in template-->       
    <xsl:template match="/test/Value[@Action='DELETE']/*[contains(name(), 'null')]" />

</xsl:stylesheet>

结果(已修改):

<test xmlns:n0="http://mynamespace">
    <Value Action="DELETE">
        <space/>
    </Value>
    <Value Action="UPDATE">
        <space/>
        <null/>
        <null2/>
    </Value>
</test>