XSLT不会在XML节点中创建标记

时间:2017-03-22 22:32:00

标签: xml xslt

我必须复制来自源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>

2 个答案:

答案 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>