Извлечь содержимое csv из тега xml

у меня есть исходный 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. Например. может быть достаточно получить доступ к каждому значению, разделенному запятой, отдельно. Это можно сделать с помощью токенизации for-each (.//non-xml-data-response, ',')

Christian Mosz 10.05.2019 11:50

да, я понимаю вашу точку зрения, мое требование состоит в том, чтобы передать весь CSV-файл в этом случае. поэтому нам не нужно концентрироваться на значениях csv индивидуально. как бы то ни было, для меня более серьезной проблемой (как вы уже догадались) является получение CSV-файла из точки общего доступа через веб-службы. связь эта ссылка может объяснить большую проблему. но пока, как я уже сказал, мне нужен весь файл csv

seetharaman 10.05.2019 12:01

Ууу. Я не думаю, что существует набор правил, который мы можем использовать для создания разрывов строк, которые будут работать с каждым CSV-документом. Согласован ли CSV-документ по своей структуре и это все данные, которые он может содержать? Если да, мы могли бы создать набор правил, например: Поместите разрыв строки перед первым большим числом. После этого мы можем поставить перенос строки после 7 запятых, которые не в кавычках. Будет ли это работать для вас?

Christian Mosz 10.05.2019 12:14

я думаю, нам не нужно беспокоиться о «большом числе», каждые семь запятых, если мы можем вставить разрыв строки, тогда все в порядке. это создаст все строки, включая заголовок, не так ли?

seetharaman 10.05.2019 13:05

Как бы вы подошли к этой задаче, если бы выполняли ее вручную? Если у вас нет способа определить, сколько отдельных значений содержится в каждой строке, эта проблема неразрешима.

michael.hor257k 10.05.2019 13:17

Тьфу, так ты просто хочешь стол из этого? Довольно просто сгруппировать каждые 7 элементов. Должен ли я написать код для преобразования csv в xml, где первые 7 записей являются именами узлов, а каждая последующая запись попадает в соответствующий тег, например: <COA>21312</COA><COA Acct Desc>"some text" </ ><Ревалуа...>...</>...?

Christian Mosz 10.05.2019 13:33
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
6
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если предположить, что строка заголовка заканчивается двоеточием и что в каждой строке данных* есть 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>:&#10;</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, '&quot;')">
                        <xsl:text>"</xsl:text>
                        <xsl:value-of select = "substring-before(substring-after($text, '&quot;'), '&quot;')"/>
                        <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>&#10;</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, '&quot;')">
                            <xsl:value-of select = "substring-after(substring-after($text, '&quot;'), '&quot;,')"/>
                        </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.

Большое усилие и умение угадывать!

Alejandro 10.05.2019 14:45

я только что получил возможность проверить результат, пожалуйста, подождите. я проверю и закрою эту тему

seetharaman 14.05.2019 08:57

трансформация работает нормально. но мой инструмент принимает любой результат, который находится внутри тега n xml. поэтому я добавил тег <result> сразу после этого <xsl:template match = "/rest-adapter-response"> . также включил </result> сразу после ` </xsl:call-template>`, но в результате я все еще не получаю этот тег результата. мой результат должен быть примерно таким, как показано ниже <result> csv content ....... </result>

seetharaman 14.05.2019 10:21

Попробуйте изменить метод вывода на xml.

michael.hor257k 14.05.2019 13:20

Другие вопросы по теме