有关如何通过XSLT映射实现此目的的任何建议
源XML:
<pay:MT_Source xmlns:pay='http://company.com/PaymentMethod' xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'>
<data contentLength='1796' contentType='text/csv;charset=UTF-8'>Company Account,Merchant Account,Reserved
Data1,Data2,Data3
Data4,Data5,Data6
Data7,Data8,Data9
</data>
</pay:MT_Source>
目标XML:
<pay:MT_Source xmlns:pay='http://company.com/PaymentMethod' xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'>
<data contentLength='1796' contentType='text/csv;charset=UTF-8'>
<record>
<Company Account>Data1</Company Account>
<Merchant Account>Data2</Merchant Account>
<Reserved>Data3<Reserved>
</record>
<record>
<Company Account>Data4</Company Account>
<Merchant Account>Data5</Merchant Account>
<Reserved>Data6<Reserved>
</record>
<record>
<Company Account>Data7</Company Account>
<Merchant Account>Data8</Merchant Account>
<Reserved>Data9<Reserved>
</record>
</data>
</pay:MT_Source>
请注意,有&#39; 

&#39;在每一行的末尾而不是逗号。
答案 0 :(得分:0)
这是一个XSLT 2.0选项。
注意:Company Account
和Merchant Account
不是有效的元素名称。我删除了空格以使它们有效。您还可以通过测试值castable as xs:QName
来检查该值是否为有效名称。
XML输入
<pay:MT_Source xmlns:pay='http://company.com/PaymentMethod' xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/'>
<data contentLength='1796' contentType='text/csv;charset=UTF-8'>Company Account,Merchant Account,Reserved
Data1,Data2,Data3
Data4,Data5,Data6
Data7,Data8,Data9
</data>
</pay:MT_Source>
XSLT 2.0
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="data[tokenize(@contentType,';') = 'text/csv']">
<xsl:copy>
<xsl:apply-templates select="@*"/>
<xsl:variable name="header-tokens" as="xs:string*">
<xsl:analyze-string select="." regex="\r\n?|\n">
<xsl:non-matching-substring>
<xsl:if test="position()=1">
<xsl:sequence select="tokenize(replace(.,'\s',''),',')"/>
</xsl:if>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:variable>
<xsl:analyze-string select="." regex="\r\n?|\n">
<xsl:non-matching-substring>
<xsl:if test="not(position()=1)">
<record>
<xsl:for-each select="tokenize(.,',')">
<xsl:variable name="pos" select="position()"/>
<xsl:element name="{$header-tokens[$pos]}">
<xsl:value-of select="."/>
</xsl:element>
</xsl:for-each>
</record>
</xsl:if>
</xsl:non-matching-substring>
</xsl:analyze-string>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
<强>输出强>
<pay:MT_Source xmlns:pay="http://company.com/PaymentMethod"
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<data contentLength="1796" contentType="text/csv;charset=UTF-8">
<record>
<CompanyAccount>Data1</CompanyAccount>
<MerchantAccount>Data2</MerchantAccount>
<Reserved>Data3</Reserved>
</record>
<record>
<CompanyAccount>Data4</CompanyAccount>
<MerchantAccount>Data5</MerchantAccount>
<Reserved>Data6</Reserved>
</record>
<record>
<CompanyAccount>Data7</CompanyAccount>
<MerchantAccount>Data8</MerchantAccount>
<Reserved>Data9</Reserved>
</record>
</data>
</pay:MT_Source>
这里的工作示例:http://xsltransform.net/6rewNyU
此外,如果csv中可能引用了带逗号的值,则可以将record
部分更改为:
<record>
<xsl:analyze-string select="."
regex=""([^"]*)",?|([^,]+),?">
<xsl:matching-substring>
<xsl:variable name="pos" select="position()"/>
<xsl:element name="{$header-tokens[$pos]}">
<xsl:value-of
select="normalize-space(concat(regex-group(1),regex-group(2)))"/>
</xsl:element>
</xsl:matching-substring>
</xsl:analyze-string>
</record>