将元素标记替换为空标记

时间:2015-09-01 09:39:01

标签: java xml xslt encoding utf-8

我的要求是使用给定方案生成一个空元素。我在Replacing the element tag with value to end tag中也有同样的看法。但是,产生的输出并不是我所期望的。

条件: 按优先顺序排列地图: 1. 如果 Test1等于Payment1,则生成此空元素<st:Test1/> 2. 否则,如果 Test2等于Payment2,则生成此空元素{{1} 3. 否则如果 Test3等于Payment3,则生成此空元素<st:Test2/>

我的XSLT:

<st:Test3/>

INPUT FILE:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:st="http://www.ebinterface.at/schema/4p1/" xmlns:po="http://schema.ebinterface.at/schema/4p1/" exclude-result-prefixes="po">
    <xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="*">
        <xsl:element name="st:{local-name()}">
            <xsl:apply-templates select="node()|@*"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="po:DEFG" priority="1">
        <st:DEFG>
            <!--handle any existing child content-->
            <xsl:apply-templates select="@* | node()"/>
            <xsl:if test="not(po:Test1)">
                <xsl:call-template name="Test1"/>
            </xsl:if>
            <xsl:if test="not(po:Test2)">
                <xsl:call-template name="Test2"/>
            </xsl:if>
            <xsl:if test="not(po:Test3)">
                <xsl:call-template name="Test3"/>
            </xsl:if>
        </st:DEFG>
    </xsl:template>
    <xsl:template match="po:Test1[.='Payment1']" name="Test1" priority="1">
        <st:Test1/>
    </xsl:template>
    <xsl:template match="po:Test2[.='Payment2']" name="Test2" priority="1">
        <st:Test2/>
    </xsl:template>
    <xsl:template match="po:Test3[.='Payment3']" name="Test3" priority="1">
        <st:Test3/>
    </xsl:template>
    <xsl:template match="*[namespace-uri()='http://www.ebinterface.at/schema/4p1/']">
        <xsl:element name="po:{local-name()}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="*[namespace-uri()='http://www.ebinterface.at/schema/4p1/']/@*">
        <xsl:attribute name="po:{local-name()}"><xsl:value-of select="."/></xsl:attribute>
    </xsl:template>
</xsl:stylesheet>

生成的输出:

<?xml version="1.0" encoding="UTF-8"?>
<Statistics xmlns="http://schema.ebinterface.at/schema/4p1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ebinterface.at/schema/4p1/" Type="abc" Title="Statistics">
     <ABC dsig="fh">Sample ABC</ABC>
     <DEFG>
        <Note>Wir ersuchen um termingerechte Bezahlung.</Note>
        <Amount currencyCode="EUR">12.36</Amount>
        <Test1>Payment1</Test1>
     </DEFG>
</Statistics>

预期输出

<?xml version="1.0" encoding="UTF-8"?>
<st:Statistics xmlns:st="http://www.ebinterface.at/schema/4p1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ebinterface.at/schema/4p1/" Type="abc" Title="Statistics">
    <st:ABC dsig="fh">Sample ABC</st:ABC>
    <st:DEFG>
        <st:Note>Wir ersuchen um termingerechte Bezahlung.</st:Note>
        <st:Amount currencyCode="EUR">12.36</st:Amount>
        <st:Test1/>
        <st:Test2/> **This empty element should not appear since there's no Test2=Payment2**
        <st:Test3/> **This empty element should not appear since there's no Test3=Payment3**
    </st:DEFG>
</st:Statistics>

提前谢谢。

非常感谢您的回复。

1 个答案:

答案 0 :(得分:2)

当您按名称调用模板时,无论该模板是否匹配,都将执行该模板。

与您的问题没有直接关系,<xsl:template match="@* | node()"><xsl:template match="*">之间也存在模板冲突。总的来说,你有太多的代码;我相信你可以做到:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:po="http://schema.ebinterface.at/schema/4p1/"
xmlns:st="http://www.ebinterface.at/schema/4p1/"
exclude-result-prefixes="po">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<!-- move elements to new namespace -->
<xsl:template match="*">
    <xsl:element name="st:{local-name()}">
        <xsl:apply-templates select="node()|@*"/>
    </xsl:element>
</xsl:template>

<!-- move attributes to new namespace -->
<xsl:template match="@*">
    <xsl:attribute name="st:{local-name()}">
        <xsl:value-of select="."/>
    </xsl:attribute>
</xsl:template>

<!-- except attributes that are NOT in the default namespace -->
<xsl:template match="@*[namespace-uri()]">
    <xsl:copy/>
</xsl:template>

<xsl:template match="po:Test1[.='Payment1']">
    <st:Test1/>
</xsl:template>

<xsl:template match="po:Test2[.='Payment2']">
    <st:Test2/>
</xsl:template>

<xsl:template match="po:Test3[.='Payment3']">
    <st:Test3/>
</xsl:template>

</xsl:stylesheet>

<强>结果

<?xml version="1.0" encoding="UTF-8"?>
<st:Statistics xmlns:st="http://www.ebinterface.at/schema/4p1/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ebinterface.at/schema/4p1/" st:Type="abc" st:Title="Statistics">
   <st:ABC st:dsig="fh">Sample ABC</st:ABC>
   <st:DEFG>
      <st:Note>Wir ersuchen um termingerechte Bezahlung.</st:Note>
      <st:Amount st:currencyCode="EUR">12.36</st:Amount>
      <st:Test1/>
   </st:DEFG>
</st:Statistics>

注意

  1. 正如您的问题所暗示的那样,这三种选择并不相互排斥。
  2. 您的预期输出格式不正确XML:如果不将其绑定到命名空间,则不能有前缀。