应用应用模板时出现问题

时间:2013-11-05 07:35:00

标签: xslt

我有一个xml,我希望得到预期的格式,如下所示。我正在尝试使用应用模板概念。但有些如何,我无法看到预期的结果。

<?xml version="1.0" encoding="UTF-8"?>
<SOAP:ENV>
    <SOAP:HEADER/>
    <SOAP:BODY>
        <OutputResponse>
            <RespStructure ID="1">
                <RespStatus>Success</RespStatus>
                <RespMessage>
                    <Country>Australia</Country>
                    <Capital>Canberra</Capital>
                </RespMessage>
                <RespMessage>
                    <Country>England</Country>
                    <Capital>London</Capital>
                </RespMessage>
                <RespMessage>
                    <Country>China</Country>
                    <Capital>Beijing</Capital>
                </RespMessage>
            </RespStructure>
        </OutputResponse>
    </SOAP:BODY>
</SOAP:ENV> 

现在在这条消息中,我将RespMessage和RespStatus作为RespStructure的一部分。但Respstatus是一个单一节点集,其中RespMessage是一个多值节点集(Country,Capital)。当我使用应用模板时,或者只有第一个RespMessage被选中(第二个重复没有出现)或者Respstatus没有给出它的值。我试着低于输出。

<?xml version="1.0" encoding="UTF-8"?>
<SOAP:ENV>
    <SOAP:HEADER/>
    <SOAP:BODY>
        <OutputResponse>
            <RespStructure ID="1">
                <TransactionStatus>Success</TransactionStatus>
                <ListOfCountries>
                    <SelectedCountry>Australia</SelectedCountry>
                    <FIrstSelectedCapital>Canberra</FIrstSelectedCapital>
                </ListOfCountries>
                <ListOfCountries>
                    <SelectedCountry>England</SelectedCountry>
                    <FIrstSelectedCapital>London</FIrstSelectedCapital>
                </ListOfCountries>
                <ListOfCountries>
                    <SelectedCountry>China</SelectedCountry>
                    <FIrstSelectedCapital>Beijing</FIrstSelectedCapital>
                </ListOfCountries>
            </RespStructure>
        </OutputResponse>
    </SOAP:BODY>
</SOAP:ENV>

我正在更改所有字段的名称,但我应该获得所有多个节点而不会丢失。

我在论坛中使用了以下代码段,但我没有申请。如何使用下面的代码片段填充RespStatus。当我给出不同的模板时,两个都没有被调用,只有一个被打印出来。我也尝试将应用模板更改为更具体的节点集。

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

<xsl:template match="Body">
    <SOAPENV>
        <Header/>
        <OutputResponse>
            <xsl:apply-templates select="@*|node()" />
        </OutputResponse>
    </SOAPENV>
</xsl:template>

<xsl:template match="RespMessage">
    <ListOfCountries>
        <SelectedCountry><xsl:value-of select="Country" /></SelectedCountry>
        <FIrstSelectedCapital><xsl:value-of select="Capital" /></FIrstSelectedCapital>
    </ListOfCountries>
</xsl:template>

感谢您的回复。对任何法术错误道歉。

1 个答案:

答案 0 :(得分:2)

查看您的XSL片段,它应匹配并转换所有 RespMessage 元素,除非XSLT的某些其他部分(您尚未显示)影响事物。

您遇到的一个问题,可能就是您编写问题的方式,原始XML使用名称空间前缀“SOAP”,但您尚未为此前缀声明名称空间。我希望第一行是这样的

<SOAP:ENV xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">

如果没有这个,您将无法在其上应用XSLT。

命名空间的使用也意味着匹配 body 的第二个模板将无法匹配任何内容

<xsl:template match="Body">

(实际上,它不匹配任何东西,因为它区分大小写,而在原始XML中它是 SOAP:BODY

查看XSLT的其余部分,如果要在不更改的情况下复制现有元素,则应使用标识模板。 XSLT中的第一个模板应如下所示

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

有了这个,你只需要添加一个匹配的模板,然后转换 RespStatus

<xsl:template match="RespStatus">
    <xsl:element name="TransactionStatus">
        <xsl:value-of select="." />
    </xsl:element>
</xsl:template>

试试这个XSLT

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/">
<xsl:output omit-xml-declaration="yes" indent="yes" />

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

<xsl:template match="RespStatus">
    <xsl:element name="TransactionStatus">
        <xsl:value-of select="." />
    </xsl:element>
</xsl:template>

<xsl:template match="RespMessage">
    <xsl:element name="ListOfCountries">
        <SelectedCountry><xsl:value-of select="Country" /></SelectedCountry>
        <FIrstSelectedCapital><xsl:value-of select="Capital" /></FIrstSelectedCapital>
    </xsl:element>
</xsl:template>
</xsl:stylesheet>