XSLT:使用for-each循环

时间:2013-09-25 19:18:29

标签: java xslt groovy

我的xslt有什么问题?
输入XML

<SaveData>
    <ClientInformation>
                                <FirstName>Steve</FirstName>
                                <LastName>Jobs</LastName>
                                <MiddleName/>
                                <DateOfBirth>09/18/2013</DateOfBirth>
                                <TaxIdentification>213465</TaxIdentification>
                                <ClientDetailPK>52385</ClientDetailPK>
                                <RoleTypeCT>OWN</RoleTypeCT>
                                <RoleTypeCT>IBE</RoleTypeCT>
                                <RoleTypeCT>Insured</RoleTypeCT>
                            </ClientInformation>
</SaveData>

OutputXML

<ContractClientVO>  
    <ContractClientPK>-1380196094967</ContractClientPK>
    <ClientRoleVO>
      <RoleTypeCT>OWN</RoleTypeCT>
      <ClientDetailVO>
        <FirstName>Steve</FirstName>
        <LastName>Jobs</LastName>
        <MiddleName/>
        <DateOfBirth>09/18/2013</DateOfBirth>
        <TaxIdentification>213465</TaxIdentification>
      </ClientDetailVO>
      <ClientRolePK>-1380196094972</ClientRolePK>
      <ClientDetailFK>52385</ClientDetailFK>
    </ClientRoleVO>
    <ClientRoleFK>-1380196094972</ClientRoleFK>
    <ContractClientPK/>
    <SegmentFK>-123456</SegmentFK>
  </ContractClientVO>

<ContractClientVO>  
    <ContractClientPK>-1380196094967</ContractClientPK>
    <ClientRoleVO>
      <RoleTypeCT>IBE</RoleTypeCT>
      <ClientDetailVO>
        <FirstName>Steve</FirstName>
        <LastName>Jobs</LastName>
        <MiddleName/>
        <DateOfBirth>09/18/2013</DateOfBirth>
        <TaxIdentification>213465</TaxIdentification>
      </ClientDetailVO>
      <ClientRolePK>-1380196094972</ClientRolePK>
      <ClientDetailFK>52385</ClientDetailFK>
    </ClientRoleVO>
    <ClientRoleFK>-1380196094972</ClientRoleFK>
    <ContractClientPK/>
    <SegmentFK>-123456</SegmentFK>
  </ContractClientVO>

<ContractClientVO>  
    <ContractClientPK>-1380196094967</ContractClientPK>
    <ClientRoleVO>
      <RoleTypeCT>Insured</RoleTypeCT>
      <ClientDetailVO>
        <FirstName>Steve</FirstName>
        <LastName>Jobs</LastName>
        <MiddleName/>
        <DateOfBirth>09/18/2013</DateOfBirth>
        <TaxIdentification>213465</TaxIdentification>
      </ClientDetailVO>
      <ClientRolePK>-1380196094972</ClientRolePK>
      <ClientDetailFK>52385</ClientDetailFK>
    </ClientRoleVO>
    <ClientRoleFK>-1380196094972</ClientRoleFK>
    <ContractClientPK/>
    <SegmentFK>-123456</SegmentFK>
  </ContractClientVO>

XSLT

 <xsl:template match="/">
        <xsl:for-each select="ClientInformation/RoleTypeCT">
        <xsl:variable name="contractClientPK" select="concat('-',timeStamp:currentTimeMillis())"/>
        <xsl:variable name="clientRolePK" select="concat('-',timeStamp:currentTimeMillis())"/>
            <ContractClientVO>
                <ContractClientPK><xsl:value-of select="$contractClientPK"/></ContractClientPK>
                <ClientRoleVO>
                    <RoleTypeCT><xsl:value-of select="RoleTypeCT"/></RoleTypeCT>
                    <ClientDetailVO>
                        <FirstName><xsl:value-of select="FirstName"/></FirstName>
                        <LastName><xsl:value-of select="LastName"/></LastName>
                        <MiddleName><xsl:value-of select="MiddleName"/></MiddleName>
                        <DateOfBirth><xsl:value-of select="DateOfBirth"/></DateOfBirth>
                        <TaxIdentification><xsl:value-of select="TaxIdentification"/></TaxIdentification>
                    </ClientDetailVO>
                    <ClientRolePK><xsl:value-of select="$clientRolePK"/></ClientRolePK>
                    <ClientDetailFK><xsl:value-of select="ClientDetailPK"/></ClientDetailFK>
                </ClientRoleVO>
                <ClientRoleFK><xsl:value-of select="$clientRolePK"/></ClientRoleFK>

            </ContractClientVO>
           </xsl:for-each>
</xsl:template>

但是我收到了这个错误

  

[致命错误]:1:692:根元素后面的文档中的标记必须格式正确。

只用一个<RoleTypeCT/>

就可以了

Groovy代码

def transformXml(xml, xslt)
    {
        def xmlAsString = groovy.xml.XmlUtil.serialize(xml)
        def w = new StringWriter()
        println XmlUtil.serialize(xml)
        println xslt
        TransformerFactory.newInstance()
                          .newTransformer( new StreamSource( new StringReader( xslt ) ) )
                          .transform( new StreamSource( new StringReader( xmlAsString ) ),
                          new StreamResult( w ) )
        return  new XmlSlurper().parseText(w.toString())
        //return w
    }

打印

<?xml version="1.0" encoding="UTF-8"?>
<ClientInformation>
  <FirstName>Steve</FirstName>
  <LastName>Jobs</LastName>
  <MiddleName/>
  <DateOfBirth>09/18/2013</DateOfBirth>
  <TaxIdentification>213465</TaxIdentification>
  <RelationshipToInsuredCT>Estate</RelationshipToInsuredCT>
  <RelationshipToEmployeeCT>Member</RelationshipToEmployeeCT>
  <SegmentFK>-123456</SegmentFK>
  <ClientDetailPK>52385</ClientDetailPK>
  <RoleTypeCT>OWN</RoleTypeCT>
  <RoleTypeCT>IBE</RoleTypeCT>
  <RoleTypeCT>Insured</RoleTypeCT>
</ClientInformation>

<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:timeStamp="java://java.lang.System" exclude-result-prefixes="timeStamp">
    <xsl:template match="ClientInformation">
          <xsl:for-each select="RoleTypeCT">
              <xsl:variable name="contractClientPK" select="concat('-',timeStamp:currentTimeMillis())"/>
              <xsl:variable name="clientRolePK" select="concat('-',timeStamp:currentTimeMillis())"/>
              <ContractClientVO>
                  <ContractClientPK><xsl:value-of select="$contractClientPK"/></ContractClientPK>
                  <ClientRoleVO>
                      <RoleTypeCT><xsl:value-of select="."/></RoleTypeCT>
                      <ClientDetailVO>
                          <FirstName><xsl:value-of select="../FirstName"/></FirstName>
                          <LastName><xsl:value-of select="../LastName"/></LastName>
                          <MiddleName><xsl:value-of select="../MiddleName"/></MiddleName>
                          <DateOfBirth><xsl:value-of select="../DateOfBirth"/></DateOfBirth>
                          <TaxIdentification><xsl:value-of select="../TaxIdentification"/></TaxIdentification>
                      </ClientDetailVO>
                      <ClientRolePK><xsl:value-of select="$clientRolePK"/></ClientRolePK>
                      <ClientDetailFK><xsl:value-of select="../ClientDetailPK"/></ClientDetailFK>
                  </ClientRoleVO>
                  <ClientRoleFK><xsl:value-of select="$clientRolePK"/></ClientRoleFK>
              </ContractClientVO>
          </xsl:for-each>
    </xsl:template>
</xsl:stylesheet>
[Fatal Error] :1:490: The markup in the document following the root element must be well-formed.
Caught: org.xml.sax.SAXParseException: The markup in the document following the root element must be well-formed.

2 个答案:

答案 0 :(得分:2)

当您匹配时,您已经在ClientInfo,而在for-each中,您要求转到ClientInfo的{​​{1}}子女。

只需使用ClientInfo将自己重新定位到select="Address"的地址子。

答案 1 :(得分:1)

是的,给定:

def xml = '''<SaveData>
    <ClientInformation>
        <FirstName>Steve</FirstName>
        <LastName>Jobs</LastName>
        <MiddleName/>
        <DateOfBirth>09/18/2013</DateOfBirth>
        <TaxIdentification>213465</TaxIdentification>
        <ClientDetailPK>52385</ClientDetailPK>
        <RoleTypeCT>OWN</RoleTypeCT>
        <RoleTypeCT>IBE</RoleTypeCT>
        <RoleTypeCT>Insured</RoleTypeCT>
    </ClientInformation>
</SaveData>'''

样式表:

def xsl = '''<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:timeStamp="java://java.lang.System" exclude-result-prefixes="timeStamp">
    <xsl:template match="ClientInformation">
        <SaveData>
            <xsl:for-each select="RoleTypeCT">
                <xsl:variable name="contractClientPK" select="concat('-',timeStamp:currentTimeMillis())"/>
                <xsl:variable name="clientRolePK" select="concat('-',timeStamp:currentTimeMillis())"/>
                <ContractClientVO>
                    <ContractClientPK><xsl:value-of select="$contractClientPK"/></ContractClientPK>
                    <ClientRoleVO>
                        <RoleTypeCT><xsl:value-of select="."/></RoleTypeCT>
                        <ClientDetailVO>
                            <FirstName><xsl:value-of select="../FirstName"/></FirstName>
                            <LastName><xsl:value-of select="../LastName"/></LastName>
                            <MiddleName><xsl:value-of select="../MiddleName"/></MiddleName>
                            <DateOfBirth><xsl:value-of select="../DateOfBirth"/></DateOfBirth>
                            <TaxIdentification><xsl:value-of select="../TaxIdentification"/></TaxIdentification>
                        </ClientDetailVO>
                        <ClientRolePK><xsl:value-of select="$clientRolePK"/></ClientRolePK>
                        <ClientDetailFK><xsl:value-of select="../ClientDetailPK"/></ClientDetailFK>
                    </ClientRoleVO>
                    <ClientRoleFK><xsl:value-of select="$clientRolePK"/></ClientRoleFK>
                </ContractClientVO>
            </xsl:for-each>
        </SaveData>
    </xsl:template>
</xsl:stylesheet>'''

(PS:时间戳不是获得PK的好方法)

我可以运行代码:

import javax.xml.transform.TransformerFactory
import javax.xml.transform.stream.StreamResult
import javax.xml.transform.stream.StreamSource

def w = new StringWriter()
TransformerFactory.newInstance()
                  .newTransformer( new StreamSource( new StringReader( xsl ) ) )
                  .transform( new StreamSource( new StringReader( xml ) ),
                  new StreamResult( w ) )
println groovy.xml.XmlUtil.serialize( w.toString() )

打印哪些:

<?xml version="1.0" encoding="UTF-8"?><SaveData>
  <ContractClientVO>
    <ContractClientPK>-1380198118176</ContractClientPK>
    <ClientRoleVO>
      <RoleTypeCT>OWN</RoleTypeCT>
      <ClientDetailVO>
        <FirstName>Steve</FirstName>
        <LastName>Jobs</LastName>
        <MiddleName/>
        <DateOfBirth>09/18/2013</DateOfBirth>
        <TaxIdentification>213465</TaxIdentification>
      </ClientDetailVO>
      <ClientRolePK>-1380198118176</ClientRolePK>
      <ClientDetailFK>52385</ClientDetailFK>
    </ClientRoleVO>
    <ClientRoleFK>-1380198118176</ClientRoleFK>
  </ContractClientVO>
  <ContractClientVO>
    <ContractClientPK>-1380198118176</ContractClientPK>
    <ClientRoleVO>
      <RoleTypeCT>IBE</RoleTypeCT>
      <ClientDetailVO>
        <FirstName>Steve</FirstName>
        <LastName>Jobs</LastName>
        <MiddleName/>
        <DateOfBirth>09/18/2013</DateOfBirth>
        <TaxIdentification>213465</TaxIdentification>
      </ClientDetailVO>
      <ClientRolePK>-1380198118176</ClientRolePK>
      <ClientDetailFK>52385</ClientDetailFK>
    </ClientRoleVO>
    <ClientRoleFK>-1380198118176</ClientRoleFK>
  </ContractClientVO>
  <ContractClientVO>
    <ContractClientPK>-1380198118177</ContractClientPK>
    <ClientRoleVO>
      <RoleTypeCT>Insured</RoleTypeCT>
      <ClientDetailVO>
        <FirstName>Steve</FirstName>
        <LastName>Jobs</LastName>
        <MiddleName/>
        <DateOfBirth>09/18/2013</DateOfBirth>
        <TaxIdentification>213465</TaxIdentification>
      </ClientDetailVO>
      <ClientRolePK>-1380198118177</ClientRolePK>
      <ClientDetailFK>52385</ClientDetailFK>
    </ClientRoleVO>
    <ClientRoleFK>-1380198118177</ClientRoleFK>
  </ContractClientVO>
</SaveData>

这就是你想要的吗?