将带有值的元素标记替换为结束标记

时间:2015-08-28 08:43:06

标签: xml xslt

我有这个要求:我需要从XML中获取元素的值,并使用空元素有条件地填充它。想到的唯一事情就是使用XSLT。

条件:如果PaymentMethodCode等于NONE,或者不存在,我需要填充此空元素:<eb:NoPayment/>

例如:

INPUT FILE:

<Invoice xmlns="http://schema.infor.com/InforOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schema.infor.com/InforOAGIS/2 http://schema.infor.com/2.12.x/InforOAGIS/BODs/SyncInvoice.xsd" Language="ger" DocumentTitle="Invoice">
     <Country CountryCode="AT">Austria</Country>
     <PaymentMethodCode>NONE</PaymentMethodCode>
</Invoice>

我的预期输出应为:

<eb:Invoice xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ebinterface.at/schema/4p1/ http://www.ebinterface.at/schema/4p1/" xmlns:eb="http://www.ebinterface.at/schema/4p1/" eb:Language="ger" eb:DocumentTitle="Invoice">>
     <eb:Country eb:CountryCode="AT">Austria</eb:Country>
     <eb:PaymentMethod>
          <eb:NoPayment/>
     </eb:PaymentMethod>
</eb:Invoice>

这可能吗?我不知道如何在XSLT中实际执行此操作。

2 个答案:

答案 0 :(得分:1)

我刚刚做了以下XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:infor="http://schema.infor.com/InforOAGIS/2" xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs" version="2.0">

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

    <xsl:template match="infor:Invoice">
        <xsl:copy>
            <xsl:choose>
                <xsl:when test="not(exists(infor:PaymentMethodCode))">
                    <xsl:element name="PaymentMethodCode" namespace="http://schema.infor.com/InforOAGIS/2">
                        <xsl:element name="NoPayment" namespace="http://schema.infor.com/InforOAGIS/2"/>
                    </xsl:element>
                </xsl:when>                
            </xsl:choose>
            <xsl:apply-templates select="*|text()|@*"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="infor:PaymentMethodCode">
        <xsl:copy>
            <xsl:choose>
                <xsl:when test="text()='NONE'">
                    <xsl:element name="NoPayment" namespace="http://schema.infor.com/InforOAGIS/2"/>
                </xsl:when>
                <xsl:when test="not(text())">
                    <xsl:element name="NoPayment" namespace="http://schema.infor.com/InforOAGIS/2"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="*|text()|@*"/>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*|text()|@*">
        <xsl:copy>
            <xsl:apply-templates select="*|text()|@*"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

如果没有给出PaymentMethodCode或者它包含值“NONE”,这将创建NoPayment元素。

输入:

<Invoice xmlns="http://schema.infor.com/InforOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schema.infor.com/InforOAGIS/2 http://schema.infor.com/2.12.x/InforOAGIS/BODs/SyncInvoice.xsd">
    <PaymentMethodCode></PaymentMethodCode>
    <PaymentMethodCode>NONE</PaymentMethodCode>
    <PaymentMethodCode>something elese</PaymentMethodCode>
</Invoice>

给出输出:

<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="http://schema.infor.com/InforOAGIS/2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schema.infor.com/InforOAGIS/2 http://schema.infor.com/2.12.x/InforOAGIS/BODs/SyncInvoice.xsd">
    <PaymentMethodCode><NoPayment/></PaymentMethodCode>
    <PaymentMethodCode><NoPayment/></PaymentMethodCode>
    <PaymentMethodCode>something elese</PaymentMethodCode>
</Invoice>

答案 1 :(得分:1)

XSLT 1.0解决方案:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:infor="http://schema.infor.com/InforOAGIS/2" 
    xmlns:eb="http://www.ebinterface.at/schema/4p1/" 
    exclude-result-prefixes="infor" 
    version="1.0">

    <xsl:template match="@* | node()">
        <xsl:copy>
            <xsl:apply-templates select="@* | node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="infor:Invoice" priority="1">
        <eb:Invoice>
            <!--handle any existing child content-->
            <xsl:apply-templates select="@* | node()"/>

            <xsl:if test="not(infor:PaymentMethodCode)">
                <!--create eb:PaymentMethodCode/eb:NoPayment-->
                <xsl:call-template name="PaymentMethodCode"/> 
            </xsl:if>
        </eb:Invoice>
    </xsl:template>

    <!--If there is not text node, or if the value is 'NONE', 
        create an empty NoPayment element-->
    <xsl:template match="infor:PaymentMethodCode[not(text()) or .='NONE']" 
                  name="PaymentMethodCode" priority="1">
        <eb:PaymentMethodCode>
          <eb:NoPayment/>
        </eb:PaymentMethodCode>
    </xsl:template>

    <!--Change the namespace for InforOAGIS elements -->
    <xsl:template match="*[namespace-uri()='http://schema.infor.com/InforOAGIS/2']">
        <xsl:element name="eb:{local-name()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <!--Change the namespace of attributes from InforOAGIS elements -->
    <xsl:template match="*[namespace-uri()='http://schema.infor.com/InforOAGIS/2']/@*">
      <xsl:attribute name="eb:{local-name()}">
          <xsl:value-of select="."/>
      </xsl:attribute>
    </xsl:template>

</xsl:stylesheet>