Запустите немного проблемы.CSV-текст, выводимый из преобразования XSLT, искажается при открытии в стороннем приложении
Я использую 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>
Некоторые образцы данных:
Перед Service Connect (после отформатирован):
<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>
После Service Connect:
<?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>
Кто там есть какие-либо идеи относительно того, что может быть причиной этой проблемы?
Я мог бы помочь вам с XSLT, но для этого потребуется немного больше ввода: знаете ли вы, какое фактическое требуемое изменение в выходе должно заставить его работать с Service Connect? Или вы можете создать пример вручную, который будет работать с Service Connect, и тот, который явно не работает? Кроме того, очень желательно использовать пример XML с минимальными входными данными. – Abel
Кстати, со скриншота, я предполагаю, что есть проблема с кодировкой. То есть таблица стилей создаст UTF-8, но, учитывая, что вы создаете CSV, ожидаемый формат для Service Connect может быть ISO-8859-1 или попробовать даже US-ASCII в качестве последнего средства (вы можете установить это в 'xsl: output'). И вы уверены, что CSV должен быть разделен на ';'? Типичный CSV имеет значение ',' (значение C для запятой, а не точки с запятой;). – Abel
Привет @Abel, спасибо, что вернулись ко мне. Мы требуем, чтобы заголовки имели символы подчеркивания (_), разделенные и замененные пробелами() для выходных столбцов CSV. Я отредактирую вопрос и предоставил два набора данных, которые я использую, чтобы достичь результата выше. Я дам кодировку выстрела - это хороший момент, вполне может и действительно быть. Что касается CSV, разделяемого точкой с запятой, мы сделали формат языка по умолчанию для точки с запятой, как разделитель, поскольку значения могут содержать запятые, но не точки с запятой. – DeeKayy90