首页 > 解决方案 > 无法从 XSLT 获取给定 XML 文件的正确信息

问题描述

我是 XSLT 的新手,第一次使用它。我有一个如下的 XML `

<?xml version="1.0" encoding="UTF-8"?>
<configuration_file>
    <source_file>
        <include>
            <global_header header_name="ABCD.H">
                <statement_comment>
                    <text> SIMPLE COMMENT</text>
                </statement_comment>
            </global_header>
            <local_header header_name="EF.H"/>
        </include>
        <const_declarations>
            <declaration_group>
                <declaration name="SimpleVariable">
                    <type>
                        <type_name>INT</type_name>
                    </type>
                    <initializer>
                        <native_initializer>
                            <statement_comment>
                                <text>COMMENT FOR VARIABLE</text>
                            </statement_comment>
                            <code>2</code>
                        </native_initializer>
                    </initializer>
                </declaration>
            </declaration_group>
        </const_declarations>
        <define>
            <macro_definition macro_name="DEFINEVARIABLE" definition="0"/>
        </define>
    </source_file>
</configuration_file>`

我在 XSLT 下试过 -

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                xmlns:fo="http://www.w3.org/1999/XSL/Format" >
<xsl:output method="text"/>

<xsl:template match="/">   
    <xsl:apply-templates select="/configuration_file/source_file" mode="configuration_file_formatter"/>
</xsl:template>

    <xsl:template match="include" mode="configuration_file_formatter">
        <xsl:for-each select="*">
         <xsl:apply-templates select="." mode="configuration_file_formatter.statement_formatter">
         <xsl:with-param name="statement">
                    <xsl:text>#include </xsl:text>
                    <xsl:choose>
                        <xsl:when test="self::global_header">
                            <xsl:text>&lt;</xsl:text>
                            <xsl:value-of select="@header_name"/>
                            <xsl:text>&gt;</xsl:text>
                            <xsl:text>&#xa;</xsl:text>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:text>"</xsl:text>
                            <xsl:value-of select="@header_name"/>
                            <xsl:text>"</xsl:text>
                            <xsl:text>&#xa;</xsl:text>
                        </xsl:otherwise>
                    </xsl:choose>
                     </xsl:with-param>
               </xsl:apply-templates>
        </xsl:for-each>
    </xsl:template>

<xsl:template match="include/global_header|
                     include/local_header"
              mode="configuration_file_formatter.statement_formatter">
    <xsl:param name="statement"/>
    <xsl:param name="line_prefix_three_char">/* </xsl:param>
    <xsl:param name="line_suffix_three_char"> */</xsl:param>
    <xsl:if test="not(statement_comment)">
        <xsl:value-of select="$statement"/>
      <xsl:text>&#xa;</xsl:text>
    </xsl:if>
    <xsl:variable name="white_spaces">
        <xsl:text>                                        </xsl:text>
    </xsl:variable>
    <xsl:for-each select="statement_comment/text">
        <xsl:variable name="line_first_segment">
            <xsl:choose>
                <xsl:when test="position()=1">
                    <xsl:choose>
                        <xsl:when test="string-length($statement) &gt; 40">
                            <xsl:value-of select="$statement"/>
                            <xsl:value-of select="$white_spaces"/>
                        </xsl:when>
                        <xsl:otherwise>
                            <xsl:value-of select="substring(concat($statement, $white_spaces), 1, 40)"/>
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:value-of select="$white_spaces"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:variable>
        <xsl:value-of select="$line_first_segment"/>
        <xsl:value-of select="$line_prefix_three_char"/>
        <xsl:value-of select="substring(concat(., $white_spaces), 1, 32)"/>
        <xsl:value-of select="$line_suffix_three_char"/>
        <xsl:text>&#xa;</xsl:text>
    </xsl:for-each>
</xsl:template> 
</xsl:stylesheet>

我得到像 -

        #include <ABCD.H>
                      /*  SIMPLE COMMENT                  */
#include "EF.H"


        
            
                
                    
                        INT
                    
                    
                        
                            
                                COMMENT FOR VARIABLE
                            
                            2
                        

有这么多额外的空间

虽然我期待输出 -

#include <ABCD.H> /* SIMPLE COMMENT */
#include "EF.H"

INT SimpleVariable=2; // COMMENT FOR VARIABLE
#define DEFINEVARIABLE 0    
    

多次尝试更改 XSLT 但有点卡在这里.. 我做错了什么?如果可用,请提供可用于 XSLT 的任何教程/注释。

标签: xmlxsltxslt-1.0

解决方案


对于这种 XML,通常最好添加

<xsl:strip-space elements="*"/>

到样式表,以消除输入 XML 中所有不需要的空格。否则,默认操作是将空格复制到输出。

有大量资源可用于学习 XSLT。请记住,印刷书籍的质量比在线教程要可靠得多。


推荐阅读