在第三方应用程序

时间:2015-08-26 01:47:56

标签: xml xslt xslt-1.0 visual-studio-2015 epicorerp

遇到一些问题。

我使用VS2015构建将在第三方程序中使用的XSLT。我已经将第三方程序(Epicor Service Connect)中的样本数据生成为XML,并基于此构建了XSLT。现在,当我调试VS中的样式表时,我得到了预期的结果 - 列顶部,分号分隔,然后每个数据块都在下面,正如预期的那样。

然而,当我通过Service Connect程序运行它时,我得到了这个完整的谜团:

Weird symbols rather than data

我需要能够使用分号作为分隔符以CSV格式返回我的数据。我在VS中获得的数据片段表明这有效:

Working data

当然,当放入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>&#xD;</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>&#xD;</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>

对于那些可能导致此问题的人有什么想法?

1 个答案:

答案 0 :(得分:2)

我很惊讶我之前没有发现这个:

由于byte order mark,您的渲染出错了!第一个字符是ISO-8859-1CP1252 (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,则可能会发生这种情况)。

要解决此问题:

  • 使用任何处理器
  • 切换到XSLT 2.0
  • 对输出进行后处理以删除字节顺序标记
  • 检查第三方软件的文档是否有删除或忽略字节顺序标记的选项
  • 使用不输出字节顺序标记的其他编码
相关问题