Как изменить данные в XML / XLST? - PullRequest
0 голосов
/ 14 февраля 2020

как я могу конвертировать XML файл, как показано ниже:

<?xml version="1.0"?>
<?xml-stylesheet href="file123.xsl" type="text/xsl"?>
    <ReportBody>
      <Document
        Title="Report: TESTOWY FIXEDHOL">
        <Chapter
        Tag="0"
        Name="TEST_KAL1_I0"
        Label=""
        Dimension="1">
          <TableDef>
        <ColLabel>
          <D>Type</D>
          <D>Month</D>
          <D>Day</D>
          <D>WeekDay</D>
        </ColLabel>
          </TableDef>
          <Bloc
        Tag="1"
        Level="1"
        Label="">
        <DataRow Total="false">
          <D>FLOAT</D>
          <D>May</D>
          <D>12</D>
          <D>Thurday</D>
        </DataRow>
          </Bloc>
        </Chapter>
      </Document>
    </ReportBody>

, чтобы добиться вот такого (конечно, это более короткий пример):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Document UploadDate="20111021" ClientCode="AKK" Version="0">
    <HolidayRules>
        <HolidayRule>
            <Type>FIXED</Type>
            <Month>August</Month>
            <Day>2.0</Day>
            <WeekDay>Friday</WeekDay>
        </HolidayRule>  
    </HolidayRules>
</UploadDocument>

Я знаю что, вероятно, я должен использовать XSLT, но как я могу это сделать? Не могли бы вы привести пример кода для этого?

Вероятно, это может быть решением, но как его использовать? что значит test = "position () = 2"? и так далее?

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl">
  <xsl:output method="xml" indent="yes"/>
  <xsl:template match="/">
    <UploadDocument>
      <xsl:for-each select="2KALROBOCZE/2VH">
        <Schedule>
          <xsl:for-each select="D">
            <xsl:if test="position() = 1">
              <Action>
                <xsl:value-of select="." />
              </Action>
            </xsl:if>
            <xsl:if test="position() = 2">
              <Name>
                <xsl:value-of select="." />
              </Name>
              <Description>&#160;</Description>
            </xsl:if>
            <xsl:if test="position() = 3">
              <DateSchedules>
                <DateSchedule>
                  <Date>
                    <xsl:value-of select="." />
                  </Date>
                </DateSchedule>
              </DateSchedules>
            </xsl:if>
          </xsl:for-each>
        </DateSchedule>
      </xsl:for-each>
    </UploadDocument>
  </xsl:template>
</xsl:stylesheet>

1 Ответ

0 голосов
/ 14 февраля 2020

Эта простая таблица стилей:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  <xsl:strip-space elements="*"/>
  <xsl:key  name="ColLabel-D-by-positionn" 
            match="ColLabel/D" 
            use="count(preceding-sibling::D) + 1"/>

  <xsl:template match="/">
    <Document UploadDate="20111021" ClientCode="AKK" Version="0">
        <HolidayRules>
            <xsl:apply-templates/>
        </HolidayRules>
    </Document>
  </xsl:template>

  <xsl:template match="DataRow">
        <HolidayRule>
            <xsl:apply-templates/>
        </HolidayRule>  
  </xsl:template>

  <xsl:template match="DataRow/D">
        <xsl:element name="{key('ColLabel-D-by-positionn', position())}">
            <xsl:value-of select="."/>    
        </xsl:element>
  </xsl:template>

  <xsl:template match="text()"/>  
</xsl:stylesheet>

Вывод:

<Document UploadDate="20111021" ClientCode="AKK" Version="0">
  <HolidayRules>
    <HolidayRule>
      <Type>FLOAT</Type>
      <Month>May</Month>
      <Day>12</Day>
      <WeekDay>Thurday</WeekDay>
    </HolidayRule>
  </HolidayRules>
</Document>

Тест на здесь

Примечание : пустое правило для текстовых узлов переопределяет встроенные правила, необходим xsl:strip-space, потому что xsl:apply-templates и position() semanti c, ключ используется для производительности и удобства, но это может быть ../../../TableDef/ColLabel/D[position() = count(current()/preceding-sibling::D) + 1]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...