我必须复制来自源xml的所有标签,并使用源数据元素(HostedAppcode)创建其他xml标签。我创建了XSLT但是,我没有得到所需的输出。请看下面。
非常感谢任何帮助!!!
XML(INPUT)
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfServerDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ServerDetails>
<ServerName>SE112935</ServerName>
<InfrastructureAppcode>VLY0</InfrastructureAppcode>
<HostedAppcode>UBD0,YND0,UGZ0,WWS0</HostedAppcode>
</ServerDetails>
<ServerDetails>
<ServerName>SE112936</ServerName>
<HostedAppcode>YND0,UGZ0,WWS0</HostedAppcode>
<FinancialAppCode>YND0,UGZ0,WWS0</FinancialAppCode>
</ServerDetails>
</ArrayOfServerDetails>
我创建的XSLT:
<?xml version='1.0'?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
<xsl:for-each select="ServerDetails">
<ServerDetails>
<HostedApplications>
<xsl:call-template name="tokenizeString">
<xsl:with-param name="list" select="HostedAppcode"/>
<xsl:with-param name="delimiter" select="','"/>
</xsl:call-template>
</HostedApplications>
</ServerDetails>
</xsl:for-each>
</xsl:template>
<xsl:template name="tokenizeString">
<!--passed template parameter -->
<xsl:param name="list"/>
<xsl:param name="delimiter"/>
<xsl:choose>
<xsl:when test="contains($list, $delimiter)">
<item>
<!-- get everything in front of the first delimiter -->
<xsl:value-of select="substring- before($list,$delimiter)"/>
</item>
<xsl:call-template name="tokenizeString">
<!-- store anything left in another variable -->
<xsl:with-param name="list" select="substring-after($list,$delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<item>
<xsl:value-of select="$list"/>
</item> `enter code here`
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
OUTPUT I GOT
<?xml version="1.0" encoding="UTF-8"?>
<ArrayOfServerDetails xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ServerDetails>
<ServerName>SE112935</ServerName>
<InfrastructureAppcode>VLY0</InfrastructureAppcode>
<HostedAppcode>UBD0,YND0,UGZ0,WWS0</HostedAppcode>
</ServerDetails>
<ServerDetails>
<ServerName>SE112936</ServerName>
<HostedAppcode>YND0,UGZ0,WWS0</HostedAppcode>
<FinancialAppCode>YND0,UGZ0,WWS0</FinancialAppCode>
</ServerDetails>
</ArrayOfServerDetails>
<ServerDetails>
<HostedApplications>
<item>UBD0</item>
<item>YND0</item>
<item>UGZ0</item>
<item>WWS0</item>
</HostedApplications>
</ServerDetails>
<ServerDetails>
<HostedApplications>
<item>YND0</item>
<item>UGZ0</item>
<item>WWS0</item>
</HostedApplications>
</ServerDetails>
希望(输出)
<?xml version="1.0" encoding="utf-8"?>
<ArrayOfServerDetails xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ServerDetails>
<ServerName>SE112935</ServerName>
<InfrastructureAppcode>VLY0</InfrastructureAppcode>
<HostedAppcode>UBD0,YND0,UGZ0,WWS0</HostedAppcode>
<HostedApplications>
<item>UBD0</item>
<item>YND0</item>
<item>UGZ0</item>
<item>WWS0</item>
</HostedApplications>
</ServerDetails>
<ServerDetails>
<ServerName>SE112936</ServerName>
<HostedAppcode>YND0,UGZ0,WWS0</HostedAppcode>
<HostedApplications>
<item>YND0</item>
<item>UGZ0</item>
<item>WWS0</item>
</HostedApplications>
<FinancialAppCode>YND0,UGZ0,WWS0</FinancialAppCode>
</ServerDetails>
</ArrayOfServerDetails>
答案 0 :(得分:0)
不要让模板中的xsl:for-each
元素ServerDetails
(与任何节点匹配),而是将其作为单独的匹配模板。
试试这个XSLT
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="ServerDetails">
<ServerDetails>
<xsl:apply-templates select="@*|node()"/>
<HostedApplications>
<xsl:call-template name="tokenizeString">
<xsl:with-param name="list" select="HostedAppcode"/>
<xsl:with-param name="delimiter" select="','"/>
</xsl:call-template>
</HostedApplications>
</ServerDetails>
</xsl:template>
<xsl:template name="tokenizeString">
<!--passed template parameter -->
<xsl:param name="list"/>
<xsl:param name="delimiter"/>
<xsl:choose>
<xsl:when test="contains($list, $delimiter)">
<item>
<!-- get everything in front of the first delimiter -->
<xsl:value-of select="substring-before($list,$delimiter)"/>
</item>
<xsl:call-template name="tokenizeString">
<!-- store anything left in another variable -->
<xsl:with-param name="list" select="substring-after($list,$delimiter)"/>
<xsl:with-param name="delimiter" select="$delimiter"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<item>
<xsl:value-of select="$list"/>
</item>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
答案 1 :(得分:0)
这是因为你正在解析&#39; <ServerDetails>
个元素两次。以下代码匹配所有元素并以递归方式复制其内容。
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
这就是产生第一组输出,它反映了现有的XML内容。然后,您使用for-each再次遍历所有<ServerDetails>
元素,并输出您指定的内容。
这是下面未经测试的代码,但基本上它应该按原样复制所有元素,但HostedAppCode元素除外。对于那个,它将首先复制它,然后输出所需的额外<item>
元素。
<xsl:template match="HostedAppcode">
<xsl:copy></xsl:copy>
<xsl:call-template name="tokenizeString">
<xsl:with-param name="list" select="text()"/>
<xsl:with-param name="delimiter" select="','"/>
</xsl:call-template>
</xsl:template>
<xsl:template match="*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>