XSLT - 创建新的XML

时间:2014-08-31 17:47:52

标签: xslt

我有一个xml A并且想要创建一个新的xml B.B的外部元素与A不同,但是一些子节点是相同的。我写了一个XSL文件,但我正在努力做到正确。谁能告诉我哪里出错了?如何将单个元素从A复制到B?问题是,当转换发生时,A中的文本被复制到B.查看以前的堆栈溢出问题,这是因为我的xsl中存在错误,但我无法弄清楚是什么。

A:

<Request>
    <Source>
        <RequestorID Client="1" EMailAddress="test@test.com" Password="pwd"/>
        <RequestorPreferences Country="JP" Currency="jpy" Language="en">
            <RequestMode>SYNCHRONOUS</RequestMode>
        </RequestorPreferences>
    </Source>
    <RequestDetails>
        <SearchHotelPriceRequest>
            <ItemDestination DestinationCode="LON" DestinationType="city"/>
            <ItemCode>98i</ItemCode>
            <PeriodOfStay>
                <CheckInDate>2015-05-20</CheckInDate>
                <CheckOutDate>2015-05-21</CheckOutDate>
            </PeriodOfStay>
            <IncludePriceBreakdown/>
            <IncludeChargeConditions/>
            <Rooms>
                <Room Code="tb" NumberOfCots="0" NumberOfRooms="1">
                    <ExtraBeds/>
                </Room>
            </Rooms>
        </SearchHotelPriceRequest>
    </RequestDetails>
</Request>

B:

<WebRequest>
    <RequestDetails>
        <WebSearchHotelPriceRequest
                CallCentreClientUI="2577"
                Client="1"
                Country="JP"
                Currency="jpy"
                Language="en"
                LoginID="">
            <GcPriceOptions ShowDeduped="true"/>
            <ItemDestination DestinationCode="LON" DestinationType="city"/>
            <ItemName></ItemName>
            <ItemCode>98i</ItemCode>
            <EffectiveDate>2014-08-15</EffectiveDate>
            <StarRatingRange>
                <Min>0</Min>
                <Max>0</Max>
            </StarRatingRange>
            <PeriodOfStay>
                <CheckInDate>2015-05-20</CheckInDate>
                <CheckOutDate>2015-05-21</CheckOutDate>
            </PeriodOfStay>
            <IncludeChargeConditions/>
            <Rooms>
                <Room Code="tb" NumberOfRooms="1"></Room>
            </Rooms>
            <SiteId>008</SiteId>
        </WebSearchHotelPriceRequest>
    </RequestDetails>
</WebRequest>

XSL:

<?xml version="1.0"?>
<xsl:stylesheet version="2.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <xsl:template match="Request">
        <xsl:element name="WebRequest">
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="RequestDetails">
        <xsl:element name="RequestDetails">
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="SearchHotelPriceRequest">
        <xsl:element name="WebSearchHotelPriceRequest">
            <xsl:attribute name="CallCentreClientUI">1</xsl:attribute>
            <xsl:attribute name="Client">1</xsl:attribute>
            <xsl:attribute name="Country">UK</xsl:attribute>
            <xsl:attribute name="Currency">GBP</xsl:attribute>
            <xsl:attribute name="Language">EN</xsl:attribute>
            <xsl:attribute name="LoginID">100</xsl:attribute>

            <SiteId>001</SiteId>
            <EffectiveDate>01-01-99</EffectiveDate>
            <xsl:apply-templates />
        </xsl:element>
    </xsl:template>

    <xsl:template match="ItemDestination">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ItemCode">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="ItemName">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="PeriodOfStay">
        <xsl:copy>
            <xsl:copy-of select="node()" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="IncludeChargeConditions">
        <xsl:copy>
            <xsl:copy-of select="node()" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="Rooms">
        <xsl:copy>
            <xsl:copy-of select="node()" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

</xsl:stylesheet> 

输出错误:

<?xml version="1.0" encoding="UTF-8"?>
<WebRequest>SYNCHRONOUS<RequestDetails>
<WebSearchHotelPriceRequest CallCentreClientUI="1" Client="1" Country="UK" Currency="GBP" Language="EN" LoginID="100">
<SiteId>001</SiteId>
<EffectiveDate>01-01-99</EffectiveDate>
<ItemDestination DestinationCode="LON" DestinationType="city"/>
<ItemCode>98i</ItemCode>
<PeriodOfStay>
<CheckInDate>2015-05-20</CheckInDate>
<CheckOutDate>2015-05-21</CheckOutDate>2015-05-202015-05-21</PeriodOfStay>
<IncludeChargeConditions/>
<Rooms>
<Room Code="tb" NumberOfCots="0" NumberOfRooms="1">
<ExtraBeds/>
</Room>
</Rooms>
</WebSearchHotelPriceRequest>
</RequestDetails>
</WebRequest>

1 个答案:

答案 0 :(得分:1)

我认为你这使得它变得比它需要的复杂得多。复制元素的最简单方法(以及它们包含的所有内容,即&#34;深拷贝&#34;)是使用xsl:copy-of。此外,如果您知道元素的名称,则不需要使用xsl:element;只是按字面输出元素。同样,对于xsl:attribute,您可以直接编写它 - 如有必要 - 使用属性值模板从输入中插入值。

以下面的样式表为例:

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

<xsl:template match="/">
    <WebRequest>
        <xsl:for-each select="Request/RequestDetails/SearchHotelPriceRequest">
            <RequestDetails>
                <WebSearchHotelPriceRequest
                    CallCentreClientUI="2577"
                    Client="2577"
                    Country="J"
                    Currency="USD"
                    Language="E"
                    LoginID="">
                    <GcPriceOptions ShowDeduped="true"/>
                    <xsl:copy-of select="ItemDestination"/>
                    <ItemName></ItemName>
                    <xsl:copy-of select="ItemCode"/>
                    <EffectiveDate>2014-08-15</EffectiveDate>
                    <StarRatingRange>
                        <Min>0</Min>
                        <Max>0</Max>
                    </StarRatingRange>
                    <xsl:copy-of select="PeriodOfStay | IncludeChargeConditions | Rooms"/>
                    <SiteId>008</SiteId>
                </WebSearchHotelPriceRequest>
            </RequestDetails>
        </xsl:for-each>
    </WebRequest>
</xsl:template>

</xsl:stylesheet>

这当然不完全是你所需要的,但我不知道哪些值会去哪里。

  

如果有人能告诉我为什么额外的文本(例如SYNCHRONOUS)是   被错误地复制了?

因为您不加选择地使用xsl:apply templates - 默认情况下使用内置模板复制文本节点。