遇到一些问题。
我使用VS2015构建将在第三方程序中使用的XSLT。我已经将第三方程序(Epicor Service Connect)中的样本数据生成为XML,并基于此构建了XSLT。现在,当我调试VS中的样式表时,我得到了预期的结果 - 列顶部,分号分隔,然后每个数据块都在下面,正如预期的那样。
然而,当我通过Service Connect程序运行它时,我得到了这个完整的谜团:
我需要能够使用分号作为分隔符以CSV格式返回我的数据。我在VS中获得的数据片段表明这有效:
当然,当放入CSV时,它会显示正确的信息。
XSLT对于任何好奇的人(请注意这是我使用XSLT的第二天,在此之前我只知道它是什么缩写 - 所以它并不太棒 - 但如果你有改进的建议,我高兴地接受建设性的批评):
<xsl:stylesheet version="1.0" xmlns:csv="csv:csv" xmlns:message="http://Epicor.com/Message/2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ext_UserSchema="http://Epicor.com/SC/UserSchema">
<xsl:output method="text" encoding="utf-8" />
<xsl:strip-space elements="*" />
<xsl:template match="message:Receiver"/>
<xsl:template match="message:Body">
<xsl:apply-templates select="message:Req"/>
</xsl:template>
<xsl:template match="message:Req">
<xsl:apply-templates select="message:Dta"/>
</xsl:template>
<xsl:template match="message:Dta">
<xsl:call-template name="PrimaryDataLoadForESC"/>
</xsl:template>
<xsl:template match="*">
<xsl:variable name="tessst" select="local-name()"/>
<xsl:choose>
<xsl:when test="$tessst = 'QueryResultDataSet'">
<xsl:call-template name="PrimaryDataLoadNotESC"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="message:Body"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="PrimaryDataLoadNotESC">
<xsl:apply-templates select="/QueryResultDataSet/Results[1]/*" mode="header"/>
<xsl:apply-templates select="/QueryResultDataSet/Results" />
</xsl:template>
<xsl:template name="PrimaryDataLoadForESC">
<xsl:apply-templates select="ext_UserSchema:QueryResultDataSet/ext_UserSchema:Results[1]/*" mode="header"/>
<xsl:apply-templates select="ext_UserSchema:QueryResultDataSet/ext_UserSchema:Results" />
</xsl:template>
<xsl:template match="*" mode="header">
<xsl:value-of select="translate(local-name(), '_', ' ')"/>
<xsl:choose>
<xsl:when test="position()=last()">
<xsl:text>
</xsl:text>
</xsl:when>
<xsl:otherwise>;</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template match="QueryResultDataSet/Results">
<xsl:apply-templates select="*" mode="dataNodes"/>
</xsl:template>
<xsl:template match="ext_UserSchema:QueryResultDataSet/ext_UserSchema:Results">
<xsl:apply-templates select="*" mode="dataNodes"/>
</xsl:template>
<xsl:template match="*" mode="dataNodes">
<xsl:value-of select="."/>
<xsl:choose>
<xsl:when test="position()=last()">
<xsl:text>
</xsl:text>
</xsl:when>
<xsl:otherwise>;</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
一些示例数据:
服务连接之前(格式化后):
<QueryResultDataSet>
<Results>
<Source_-_System>SOURCE SYSTEM 1</Source_-_System>
<Customer>96247</Customer>
<Description_-_Short>COMPANY DESCRIPTION SHORT</Description_-_Short>
<Description_-_Medium>COMPANY DESCRIPTION MEDIUM</Description_-_Medium>
<Description_-_Long>COMPANY DESCRIPTION LONG</Description_-_Long>
</Results>
服务后连接:
<?xml version="1.0" encoding="utf-16"?>
<msg:Msg xsi:schemaLocation="http://Epicor.com/Message/2.0 http://scshost/schemas/epicor/ScalaMessage.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:msg="http://Epicor.com/Message/2.0">
<msg:Hdr>
<msg:Ctrl>
<msg:MsgID></msg:MsgID>
</msg:Ctrl>
<msg:Sender>
<msg:Name></msg:Name>
<msg:Subname></msg:Subname>
</msg:Sender>
<msg:Logon></msg:Logon>
</msg:Hdr>
<msg:Body>
<msg:Req msg-type="DocumentToProcess" action="MapAndProcess">
<msg:Dta>
<ext_UserSchema:QueryResultDataSet xmlns:msg="http://Epicor.com/InternalMessage/1.1" xmlns:ext_UserSchema="http://Epicor.com/SC/UserSchema">
<ext_UserSchema:Results>
<ext_UserSchema:Source_System>SOURCE_SYS1</ext_UserSchema:Source_System>
<ext_UserSchema:Vendor>96247</ext_UserSchema:Vendor>
<ext_UserSchema:Description_-_Short>COMPANY DESCRIPTION SHORT</ext_UserSchema:Description_-_Short>
<ext_UserSchema:Description_-_Medium>COMPANY DESCRIPTION MEDIUM</ext_UserSchema:Description_-_Medium>
<ext_UserSchema:Description_-_Long>COMPANY DESCRIPTION LONG</ext_UserSchema:Description_-_Long>
</ext_UserSchema:Results>
</ext_UserSchema:QueryResultDataSet>
</msg:Dta>
</msg:Req>
</msg:Body>
</msg:Msg>
对于那些可能导致此问题的人有什么想法?
答案 0 :(得分:2)
我很惊讶我之前没有发现这个:
由于byte order mark,您的渲染出错了!第一个字符是ISO-8859-1,CP1252 (windows)或Unicode 0xFF 'ÿ'和第二个0xFE 'þ'的呈现,它们是使用UTF时字节顺序标记中的第一个和第二个字节-16(顺序取决于字节顺序),或者当使用UTF-8并应用UTF-8解码时(字节为0xEF,0xBB 0xBF)。
因此,简而言之,要解决此问题,请将xsl:output
更改为包含:
<xsl:output byte-order-mark="no" />
但这只适用于XSLT 2.0或更高版本。如果无法切换到XSLT 2.0,则应检查处理器的文档,如果它支持不带字节顺序标记的UTF-8编码。
至少在某些时候,使用带有UTF-8的文本输出时the Saxon processor output a byte order mark。此外,在Windows上,记事本和许多其他编辑器在保存文件时会自动发出字节顺序标记(例如,如果您手动编辑CSV,则可能会发生这种情况)。
要解决此问题: