从XML数据中获取正确的数据(使用XSLT)

时间:2019-04-22 23:05:18

标签: xml xslt xpath xslt-1.0 xslt-2.0

我希望从多个节点中获取数据,但是很难找到一种使数据按我想要的方式工作的方法。

样本数据:

<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>

我希望能够从OfferAmount字段中获取77000.0,也可以从StartDate中获取2019年4月26日。我需要在XSLT中创建的逻辑是,在LatestStep中找到要约的最新步骤为10。然后,在等号后获取数据。

    <!-- 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 :(得分:0)

要提取日期,可以使用:

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>

答案 1 :(得分:0)

使用此类数据,通常最好分多个阶段进行处理。第一阶段:将其转换为结构化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以通常的方式将美国(mm / dd / yyyy)日期转换为ISO格式。

然后第二阶段变得无关紧要。