Задать вопрос
eliasum
@eliasum
cd ..

Как исправить файл стиля xsl?

Есть xml файл:
<Station  >
  <Equip   key="_key">
    <Mode  >
      <Item key="Auto"  >
        <Command  >
          <Item key="Run"   />
          <Item key="Break"   />
          <Item key="Pause"   />
          <Item key="Continue"   />
        </Command>
      </Item>
      <Item key="Manual"   />
    </Mode>
    <Command  >
      <Item key="Run"   />
      <Item key="Break"   />
      <Item key="Pause"   />
      <Item key="Continue"   />
    </Command>
    <Slot  >
      <Item key="1"  >
        <Mode  >
          <Item key="Auto"  >
            <Command  >
              <Item key="Run"   />
              <Item key="Break"   />
              <Item key="Pause"   />
              <Item key="Continue"   />
            </Command>
          </Item>
          <Item key="Manual"   />
        </Mode>
        <Product  >
          <SerialNumber   value="" />
          <Info   value="" />
        </Product>
        <Supply  >
          <Item key="Ph"  >
            <Amperage   symbol="I" unit="[А]" format="F1" value="">
              <Allowance   symbol="Δ" unit="[%]" value="3" />
            </Amperage>
            <Voltage   symbol="U" unit="[В]" format="N0" value="">
              <Allowance   symbol="Δ" unit="[%]" value="3" />
            </Voltage>
          </Item>
          <Item key="Mc1"  >
            <Amperage   symbol="I" unit="[А]" format="F1" value="">
              <Allowance   symbol="Δ" unit="[%]" value="3" />
            </Amperage>
            <Voltage   symbol="U" unit="[В]" format="N0" value="">
              <Allowance   symbol="Δ" unit="[%]" value="3" />
            </Voltage>
          </Item>
          <Item key="Mc12"  >
            <Amperage   symbol="I" unit="[А]" format="F1" value="">
              <Allowance   symbol="Δ" unit="[%]" value="3" />
            </Amperage>
            <Voltage   symbol="U" unit="[В]" format="N0" value="">
              <Allowance   symbol="Δ" unit="[%]" value="3" />
            </Voltage>
          </Item>
          <Item key="Mc2"  >
            <Amperage   symbol="I" unit="[А]" format="F1" value="">
              <Allowance   symbol="Δ" unit="[%]" value="3" />
            </Amperage>
            <Voltage   symbol="U" unit="[В]" format="N0" value="">
              <Allowance   symbol="Δ" unit="[%]" value="3" />
            </Voltage>
          </Item>
          <Item key="An"  >
            <Amperage   symbol="I" unit="[А]" format="F1" value="">
              <Allowance   symbol="Δ" unit="[%]" value="3" />
            </Amperage>
            <Voltage   symbol="U" unit="[В]" format="N0" value="">
              <Allowance   symbol="Δ" unit="[%]" value="3" />
            </Voltage>
          </Item>
        </Supply>
        <Command  >
          <Item key="Run"   />
          <Item key="Break"   />
          <Item key="Pause"   />
          <Item key="Continue"   />
        </Command>
      </Item>
    </Slot>
    <Chart   />
  </Equip>
</Station>


Из которого с помощью файла стилей xsl:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="text" encoding="UTF-8"/>
  <xsl:variable name="apostrophe">'</xsl:variable>
  <xsl:template match="/">
<xsl:text>
CREATE TABLE table (
    key integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    config text NOT NULL,
    allowance float NOT NULL,
    tablename character(15) NOT NULL,
    CONSTRAINT "table_key" PRIMARY KEY (key)
);

INSERT INTO table (config, allowance, tablename) VALUES 
</xsl:text>
    <xsl:apply-templates/>
    <xsl:text>;</xsl:text>
  </xsl:template>
  
  <xsl:template match="node()[@format]">
    <xsl:variable name="allowance" select="Allowance/@value"/>
    <xsl:value-of select="concat('(', $apostrophe)"/>
    <xsl:for-each select="ancestor::*">
      <xsl:variable name="element" select="local-name()"/>
      <xsl:value-of select="$element"/>
      <xsl:if test="$element='Item'">
        <xsl:value-of select="concat('[@key=', $apostrophe, $apostrophe, @key, $apostrophe, $apostrophe, ']')"/>
      </xsl:if>
      <xsl:text>/</xsl:text>
    </xsl:for-each>
    <xsl:choose>
      <xsl:when test="starts-with(@format, 'N')">
        <xsl:value-of select="concat(local-name(), $apostrophe, ', ', $allowance, ', ', $apostrophe, 'number_actual', $apostrophe, '),')"/>
      </xsl:when>
      <xsl:when test="starts-with(@format, 'F')">
        <xsl:value-of select="concat(local-name(), $apostrophe, ', ', $allowance, ', ', $apostrophe, 'float_actual', $apostrophe, '),')"/>
      </xsl:when>
      <xsl:when test="starts-with(@format, 'D')">
        <xsl:value-of select="concat(local-name(), $apostrophe, ', ', $allowance, ', ', $apostrophe, 'decimal_actual', $apostrophe, '),')"/>
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="concat(local-name(), $apostrophe, ', ', $allowance, ', ', $apostrophe, 'string_actual', $apostrophe, '),')"/>
      </xsl:otherwise>
    </xsl:choose>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>


Генерируется sql скрипт:
CREATE TABLE table (
    key integer NOT NULL GENERATED ALWAYS AS IDENTITY ( INCREMENT 1 START 1 MINVALUE 1 MAXVALUE 2147483647 CACHE 1 ),
    config text NOT NULL,
    allowance float NOT NULL,
    tablename character(15) NOT NULL,
    CONSTRAINT "table_key" PRIMARY KEY (key)
);

INSERT INTO table (config, allowance, tablename) VALUES 
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Ph'']/Amperage', 3, 'float_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Ph'']/Voltage', 3, 'number_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc1'']/Amperage', 3, 'float_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc1'']/Voltage', 3, 'number_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc12'']/Amperage', 3, 'float_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc12'']/Voltage', 3, 'number_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc2'']/Amperage', 3, 'float_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc2'']/Voltage', 3, 'number_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''An'']/Amperage', 3, 'float_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''An'']/Voltage', 3, 'number_actual'),
;


У sql скрипта в самом конце лишняя запятая, а точка с запятой с новой строки, из-за чего скрипт не рабочий, пока его не исправишь в ручную. Как переписать файл стиля xsl, чтобы вконце sql скрипта код был сгенерирован правильно автоматически:
...
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc2'']/Voltage', 3, 'number_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''An'']/Amperage', 3, 'float_actual'),
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''An'']/Voltage', 3, 'number_actual');
  • Вопрос задан
  • 71 просмотр
Подписаться 2 Простой Комментировать
Решения вопроса 1
@alexalexes
Сложно сделать first- или last- специфичный выходной элемент, так как нельзя внятно получить значение position.
Однако, можно воспользоваться таким костылем:
1) Вывести запятую и перенос строки впереди очередного элемента VALUES, сохранив перенос после элемента.
2) Закомментировать лишнюю запятую в запросе.
То есть добиться такого вывода:
INSERT INTO table (config, allowance, tablename) VALUES --,
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Ph'']/Amperage', 3, 'float_actual')
,
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Ph'']/Voltage', 3, 'number_actual')
,
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc1'']/Amperage', 3, 'float_actual')
,
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc1'']/Voltage', 3, 'number_actual')
,
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc12'']/Amperage', 3, 'float_actual')
,
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc12'']/Voltage', 3, 'number_actual')
,
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc2'']/Amperage', 3, 'float_actual')
,
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''Mc2'']/Voltage', 3, 'number_actual')
,
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''An'']/Amperage', 3, 'float_actual')
,
('Station/Equip/Slot/Item[@key=''1'']/Supply/Item[@key=''An'']/Voltage', 3, 'number_actual')
;

Правило:
INSERT INTO table (config, allowance, tablename) VALUES --</xsl:text><xsl:apply-templates/>
    <xsl:text>;</xsl:text>
  </xsl:template>
  
  <xsl:template match="node()[@format]">
    <xsl:variable name="allowance" select="Allowance/@value"/>
   <xsl:text>,&#10;</xsl:text> <!-- Сюда добавлены запятая и перенос -->    
<xsl:value-of select="concat('(', $apostrophe)"/>
    <xsl:for-each select="ancestor::*">
      <xsl:variable name="element" select="local-name()"/>
      <xsl:value-of select="$element"/>
      <xsl:if test="$element='Item'">
        <xsl:value-of select="concat('[@key=', $apostrophe, $apostrophe, @key, $apostrophe, $apostrophe, ']')"/>
      </xsl:if>
      <xsl:text>/</xsl:text>
    </xsl:for-each>
    <xsl:choose>
      <xsl:when test="starts-with(@format, 'N')">
        <xsl:value-of select="concat(local-name(), $apostrophe, ', ', $allowance, ', ', $apostrophe, 'number_actual', $apostrophe, ')')"/> <!--убран вывод последней запятой -->
      </xsl:when>
      <xsl:when test="starts-with(@format, 'F')">
        <xsl:value-of select="concat(local-name(), $apostrophe, ', ', $allowance, ', ', $apostrophe, 'float_actual', $apostrophe, ')')"/> <!--убран вывод последней запятой -->
      </xsl:when>
      <xsl:when test="starts-with(@format, 'D')">
        <xsl:value-of select="concat(local-name(), $apostrophe, ', ', $allowance, ', ', $apostrophe, 'decimal_actual', $apostrophe, ')')"/> <!--убран вывод последней запятой -->
      </xsl:when>
      <xsl:otherwise>
        <xsl:value-of select="concat(local-name(), $apostrophe, ', ', $allowance, ', ', $apostrophe, 'string_actual', $apostrophe, ')')"/> <!--убран вывод последней запятой -->
      </xsl:otherwise>
    </xsl:choose>
    <xsl:text>&#10;</xsl:text>
  </xsl:template>
  <xsl:template match="text()"/>
</xsl:stylesheet>
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы