exsl:xsl中的文档:if block

时间:2016-08-09 13:52:38

标签: xml perl xslt

这是我用例的低调版本。

1)我有一个转换xsl文件,如下所示

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xalan="http://xml.apache.org/xslt"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:exsl="http://exslt.org/common"
    extension-element-prefixes="exsl">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes" media-type="text/xml"/>

    <xsl:param name="isfile"/>

    <xsl:variable name="dotransformation">
        <xsl:choose>
            <xsl:when test="$isfile = 'true'"> 
                <xsl:value-of select="true()"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="false()"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable>

    <xsl:template match="/">
        <xsl:if test="$dotransformation = true()">
            <exsl:document href = "outputfile1.xml" method="xml" version="1.0" encoding="UTF-8" indent="yes">                  
                Article:- <xsl:value-of select="/Article/Title"/>
                Authors:- <xsl:apply-templates select="/Article/Authors/Author"/>
            </exsl:document>
        </xsl:if>
    </xsl:template>

    <xsl:template match="Author">
        <exsl:document href = "outputfile2.xml" method="xml" version="1.0" encoding="UTF-8" indent="yes">                  
            always Generate this output!! <xsl:value-of select="." />
        </exsl:document>
    </xsl:template>
</xsl:stylesheet>

2)我有一个需要转换的示例文件,需要根据xsl文件中的条件生成输出output1.xmloutput2.xml

<?xml version="1.0"?>
<?xml-stylesheet type="xsl" href="trans.xsl"?>
<Article>
  <Title>My Article</Title>
  <Authors>
    <Author>Mr. Foo</Author>
    <Author>Mr. Bar</Author>
  </Authors>
  <Body>This is my article text.</Body>
</Article>

3)这是我用于转换的perl脚本

#!/usr/local/bin/perl -w

use strict;
use warnings;
use File::Path;
use File::Spec;
use File::Basename;
use XML::LibXSLT;
use XML::LibXML;

my $isfile;

my ($xmlfile,$xsltfile,$samplefile) = qw/ Example.xml trans.xsl sample.xml/;

if(-f $samplefile)
{
    $isfile = "true";
    print "File is present\n";
}
else
{
    $isfile = "false";
    print "File is absent\n";
}

my %args = ( "isfile" => $isfile ); 
my $xslt = XML::LibXSLT->new;
my $stylesheet = $xslt->parse_stylesheet_file($xsltfile);
my $results  = 
$stylesheet->transform_file($xmlfile,XML::LibXSLT::xpath_to_string(%{args}));
0;

在我的perl脚本中,我提供了一个名为$isfile的参数,用于检查目录中是否有其他文件sample.xml,并相应地设置其值。

我收到了xsl转换模板文件的参数,并从中创建了一个新变量dotransformation

我需要仅在output1.xml具有真值时生成$dotransformation,否则应生成output2.xml

但是,即使目录中不存在sample.xmlexsl:document也会同时生成output1.xmloutput2.xml,而不只是output2.xml

为什么会这样? exsl:document不能与xsl:if一起使用吗?

1 个答案:

答案 0 :(得分:1)

这里的主要问题是您将dotransformation定义为结果树片段而不是布尔值。只有空片段为 false ,因此您的测试$dotransformation = true()始终为 true

您有几个选择。最明显的是将真实的布尔值放入dotransformation这样的

<xsl:variable name="dotransformation" select="$isfile = 'true'" />

然后您现有的测试将起作用,或者您可以说

<xsl:if test="$dotransformation">

或者,当然,您可以简单地写一下

<xsl:if test="$isfile = 'true'">

忘了中间变量

另一个问题是match="Author"模板的执行只是因为你有

<xsl:apply-templates select="/Article/Authors/Author" />

在条件部分内。如果该部分被禁用,则没有任何东西可以导致根节点下面的任何内容被处理,并且就目前而言,都不会生成任何文件

解决方案是在其中放置一个简单的递归模板,使处理器能够遍历所有元素层

<xsl:template match="*">
    <xsl:apply-templates select="*" />
</xsl:template>