у меня есть исходный xml, как показано ниже
<rest-adapter-response>
<metadata>
<status>success</status>
</metadata>
<status-line>
<code>200</code>
<reason>OK</reason>
</status-line>
<header-lines>
<Cache-Control>private, max-age=0</Cache-Control>
<Transfer-Encoding>chunked</Transfer-Encoding>
<Content-Type>application/octet-stream</Content-Type>
<Expires>Thu, 25 Apr 2019 08:51:55 GMT</Expires>
<Last-Modified>Fri, 10 May 2019 08:51:55 GMT</Last-Modified>
<Server>Microsoft-IIS/10.0</Server>
<X-SharePointHealthScore>1</X-SharePointHealthScore>
<X-SP-SERVERSTATE>ReadOnly=0</X-SP-SERVERSTATE>
<DATASERVICEVERSION>3.0</DATASERVICEVERSION>
<X-Download-Options>noopen</X-Download-Options>
<Content-Disposition>attachment</Content-Disposition>
<SPClientServiceRequestDuration>224</SPClientServiceRequestDuration>
<X-AspNet-Version>4.0.30319</X-AspNet-Version>
<SPRequestGuid>de31db9e-70cb-8000-7fba-6c3e85d9c810</SPRequestGuid>
<request-id>de31db9e-70cb-8000-7fba-6c3e85d9c810</request-id>
<MS-CV>ntsx3stwAIB/umw+hdnIEA.0</MS-CV>
<Strict-Transport-Security>max-age=31536000</Strict-Transport-Security>
<X-FRAME-OPTIONS>SAMEORIGIN</X-FRAME-OPTIONS>
<X-Powered-By>ASP.NET</X-Powered-By>
<MicrosoftSharePointTeamServices>16.0.0.8824</MicrosoftSharePointTeamServices>
<X-Content-Type-Options>nosniff</X-Content-Type-Options>
<X-MS-InvokeApp>1; RequireReadOnly</X-MS-InvokeApp>
<P3P>CP = "ALL IND DSP COR ADM CONo CUR CUSo IVAo IVDo PSA PSD TAI TELo OUR SAMo CNT COM INT NAV ONL PHY PRE PUR UNI"</P3P>
<Date>Fri, 10 May 2019 08:51:55 GMT</Date>
</header-lines>
<message-body>
<non-xml-data-response>COA,COA Acct Desc,Acct Prefix,Revaluation Acct,Mapping Changes - Additions( A ) Deletions ( D ) Changes ( C ),MJE,OIM Recon,Comments for difference:10000274,"Citibank, Operating, USD, 31165975",1000,10009999,A,,X,10000374,"Citibank, Clearing, USD, 31165975",1000,10009999,A,,X,10006604,"HSBC, Operating, SAR, SA0345000000003179660002",1000,10009999,A,,X,10006605,"Citibank, Operating, ZAR, 0202099009",1000,10009999,A,,X,123,,,456,,,,</non-xml-data-response>
</message-body>
</rest-adapter-response>
XML выше — это ответ веб-службы точки обмена, которая попыталась прочитать CSV-файл и дала такой ответ. как вы можете видеть в приведенном выше ответе xml, данные csv действительно пришли, но внутри одного тега xmltag с именем <message-body>, а также потеряли новую строку после каждого формата строки!!
теперь мне нужно воссоздать csv !!. и хуже всего то, что в инструменте, где я получаю этот формат, у меня есть возможность писать xslt и xml! нельзя было использовать код языка хостинга или библиотеки. тоже только xslt 1.0.
есть такой вопрос вопрос по созданию csv из xml, но это немного отличается от моего требования. Я только изучаю xslt и xpath, может ли кто-нибудь помочь мне в этом?
ниже приведен запрошенный вывод: нажмите здесь, чтобы просмотреть формат csv
да, я понимаю вашу точку зрения, мое требование состоит в том, чтобы передать весь CSV-файл в этом случае. поэтому нам не нужно концентрироваться на значениях csv индивидуально. как бы то ни было, для меня более серьезной проблемой (как вы уже догадались) является получение CSV-файла из точки общего доступа через веб-службы. связь эта ссылка может объяснить большую проблему. но пока, как я уже сказал, мне нужен весь файл csv
Ууу. Я не думаю, что существует набор правил, который мы можем использовать для создания разрывов строк, которые будут работать с каждым CSV-документом. Согласован ли CSV-документ по своей структуре и это все данные, которые он может содержать? Если да, мы могли бы создать набор правил, например: Поместите разрыв строки перед первым большим числом. После этого мы можем поставить перенос строки после 7 запятых, которые не в кавычках. Будет ли это работать для вас?
я думаю, нам не нужно беспокоиться о «большом числе», каждые семь запятых, если мы можем вставить разрыв строки, тогда все в порядке. это создаст все строки, включая заголовок, не так ли?
Как бы вы подошли к этой задаче, если бы выполняли ее вручную? Если у вас нет способа определить, сколько отдельных значений содержится в каждой строке, эта проблема неразрешима.
Тьфу, так ты просто хочешь стол из этого? Довольно просто сгруппировать каждые 7 элементов. Должен ли я написать код для преобразования csv в xml, где первые 7 записей являются именами узлов, а каждая последующая запись попадает в соответствующий тег, например: <COA>21312</COA><COA Acct Desc>"some text" </ ><Ревалуа...>...</>...?





Если предположить, что строка заголовка заканчивается двоеточием и что в каждой строке данных* есть 7 значений, то можно использовать следующую таблицу стилей:
XSLT 1.0
<xsl:stylesheet version = "1.0"
xmlns:xsl = "http://www.w3.org/1999/XSL/Transform">
<xsl:output method = "text" encoding = "UTF-8"/>
<xsl:template match = "/rest-adapter-response">
<xsl:variable name = "csv" select = "message-body/non-xml-data-response" />
<!-- header -->
<xsl:value-of select = "substring-before($csv, ':')" />
<xsl:text>: </xsl:text>
<!-- data -->
<xsl:call-template name = "restore-csv">
<xsl:with-param name = "text" select = "substring-after($csv, ':')"/>
</xsl:call-template>
</xsl:template>
<xsl:template name = "restore-csv">
<xsl:param name = "text"/>
<xsl:param name = "i" select = "1"/>
<xsl:choose>
<xsl:when test = "contains($text, ',')">
<xsl:variable name = "value">
<xsl:choose>
<xsl:when test = "starts-with($text, '"')">
<xsl:text>"</xsl:text>
<xsl:value-of select = "substring-before(substring-after($text, '"'), '"')"/>
<xsl:text>"</xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select = "substring-before($text, ',')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:variable>
<!-- output -->
<xsl:value-of select = "$value"/>
<xsl:choose>
<xsl:when test = "$i mod 7 = 0">
<xsl:text> </xsl:text>
</xsl:when>
<xsl:otherwise>
<xsl:text>,</xsl:text>
</xsl:otherwise>
</xsl:choose>
<!-- recursive call -->
<xsl:call-template name = "restore-csv">
<xsl:with-param name = "text">
<xsl:choose>
<xsl:when test = "starts-with($text, '"')">
<xsl:value-of select = "substring-after(substring-after($text, '"'), '",')"/>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select = "substring-after($text, ',')"/>
</xsl:otherwise>
</xsl:choose>
</xsl:with-param>
<xsl:with-param name = "i" select = "$i + 1"/>
</xsl:call-template>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select = "$text"/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Применительно к вашему примеру ввода результат будет таким:
Результат
COA,COA Acct Desc,Acct Prefix,Revaluation Acct,Mapping Changes - Additions( A ) Deletions ( D ) Changes ( C ),MJE,OIM Recon,Comments for difference:
10000274,"Citibank, Operating, USD, 31165975",1000,10009999,A,,X
10000374,"Citibank, Clearing, USD, 31165975",1000,10009999,A,,X
10006604,"HSBC, Operating, SAR, SA0345000000003179660002",1000,10009999,A,,X
10006605,"Citibank, Operating, ZAR, 0202099009",1000,10009999,A,,X
123,,,456,,,
Это может потребовать дополнительной работы для обработки возможных экранированных двойных кавычек внутри значений в кавычках.
--
(*) Странно то, что в строке заголовка 8 значений, а в строках данных только 7.
Большое усилие и умение угадывать!
я только что получил возможность проверить результат, пожалуйста, подождите. я проверю и закрою эту тему
трансформация работает нормально. но мой инструмент принимает любой результат, который находится внутри тега n xml. поэтому я добавил тег <result> сразу после этого <xsl:template match = "/rest-adapter-response"> . также включил </result> сразу после ` </xsl:call-template>`, но в результате я все еще не получаю этот тег результата. мой результат должен быть примерно таким, как показано ниже <result> csv content ....... </result>
Попробуйте изменить метод вывода на xml.
Есть ли у вас определенный набор правил, когда делать разрывы строк? Было бы полезно знать, для чего вам нужен csv. Возможно, мы сможем найти другое решение без воссоздания csv. Например. может быть достаточно получить доступ к каждому значению, разделенному запятой, отдельно. Это можно сделать с помощью токенизации for-each (.//non-xml-data-response, ',')