Получение правильных данных из XML-данных (с использованием XSLT) - PullRequest
0 голосов
/ 23 апреля 2019

Я хочу получить данные с нескольких узлов, но не могу найти способ заставить его работать так, как я хочу.

Пример данных:

<Records>
  <Record>
    <ID>100</ID>
    <LatestStep>(Offers:1)=9;(Offers:2)=10;(Offers:3)=7</LatestStep>
    <OfferAmount>(Offers:1)=90000.0;(Offers:2)=77000.0;(Offers:3)=75999.0</OfferAmount>
    <StartDate>(Offers:1)=04/24/2019;(Offers:2)=04/26/2019;(Offers:3)=04/28/2019</StartDate>
    <OfferAmount>(Offers:1)=90000.0;(Offers:2)=77000.0;</OfferAmount>
  </Record>
<Records>

Я бы хотел иметь возможность получить 77000.0 из поля OfferAmount, а также 26.04.2009 из StartDate. Логика, которую мне нужно создать в XSLT, состоит в том, чтобы найти предложение, которое имеет последний шаг из 10 в LatestStep. Затем возьмите данные после знака равенства.

    <!-- Current Code (example) -->
    <xsl:variable name="record" select="."/>
    <xsl:variable name="offers">
        <xsl:analyze-string select="LatestStep"regex="\(Offers:([\d]+)\)=10">
            <xsl:matching-substring>
                <offer>
                    <payAmount>
                        <xsl:value of select="tokenize(replace($record/OfferAmount, '\(Offers:[\d]+\)=',''),';')
                    </payAmount>
                </offer>

Ответы [ 2 ]

0 голосов
/ 23 апреля 2019

С такими данными часто лучше решать это в несколько этапов. Первый этап: превратить его в структурированный XML, тот тип XML, который вы бы предпочли получить в первую очередь; второй этап, захватите фактические данные, которые вам нужны.

Причина этого в том, что первый этап часто можно использовать повторно; Вы можете применить к данным одну и ту же предварительную обработку независимо от того, что вы хотите с ней делать потом.

Я понятия не имею, что представляет собой фактическая модель данных или что вы можете найти в других примерах вашего ввода, но если вы хотите включить

<StartDate>(Offers:1)=04/24/2019;(Offers:2)=04/26/2019;(Offers:3)=04/28/2019</StartDate>

в

<StartDate>
  <Offers nr="1">2019-04-24</Offers>
  <Offers nr="2">2019-04-26</Offers>
  <Offers nr="3">2019-04-28</Offers>
</StartDate>

Тогда вы можете сделать это с

<xsl:template match="StartDate|...">
  <xsl:copy>
    <xsl:for-each select="tokenize(., ';')">
      <Offers nr="{position()}>
        <xsl:value-of select="my:us-date-to-iso(substring-after(., '='))"/>
      </Offers>
    </xsl:for-each>
  </xsl:copy>
</xsl:template>

где my: us-date-to-iso конвертирует американские (мм / дд / гггг) даты в формат ISO обычным способом.

Тогда вторая фаза становится тривиальной.

0 голосов
/ 23 апреля 2019

Чтобы извлечь дату, вы можете использовать:

XSLT 2.0

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="Record">
    <xsl:variable name="prefix" select="substring-before(tokenize(LatestStep, ';')[ends-with(., '=10')], '=10')" />
     <offer>
        <date>
             <xsl:value-of select="substring-after(tokenize(StartDate, ';')[starts-with(., $prefix)], concat($prefix, '='))" />
        </date>
    </offer>
</xsl:template>

</xsl:stylesheet>
...