xmlhack.ru XML-форумы
Обсуждение XML и связанных с ним технологий

Преобразование XML


Автор Сообщение
svn
Новичок

Зарегистрирован: 17.02.2009
Сообщения: 2

[13565] Вт Фев 17, 2009 08:19
Преобразование XML
Прошу прощения, нет опыта работы с XSLT

Нужно исходный файл:
<?xml version="1.0" encoding="windows-1251"?>
<BODY>
<msg_typ>1</msg_typ>
<msg_date>01/10/2008</msg_date>
<block1>
<dokum>
<dokum_num>1</dokum_num>
<sklad_1>
<tbl_1>
<tbl_2>
<tbl_3>
<id>100</id>
</tbl_3>
</tbl_2>
</tbl_1>
</sklad_1>
<sklad_2>
<tbl_1>
<tbl_2>
<tbl_3>
<id>200</id>
</tbl_3>
</tbl_2>
</tbl_1>
</sklad_2>
</dokum>
<dokum>
<dokum_num>2</dokum_num>
<sklad_1>
<tbl_1>
<tbl_2>
<tbl_3>
<id>400</id>
</tbl_3>
</tbl_2>
</tbl_1>
</sklad_1>
<sklad_2>
<tbl_1>
<tbl_2>
<tbl_3>
<id>400</id>
</tbl_3>
</tbl_2>
</tbl_1>
</sklad_2>
</dokum>
</block1>
</BODY>

Преобразовать в:
<BODY>
<dokum>
<sklad_1_Id>100</sklad_1_Id>
<sklad_2_Id>200</sklad_2_Id>
</dokum>
<dokum>
<sklad_1_Id>300</sklad_1_Id>
<sklad_2_Id>400</sklad_2_Id>
</dokum>
</BODY>

Делаю:
<?xml version="1.0" encoding="windows-1251" ?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
exclude-result-prefixes="xsl msxsl xsd msdata xsi">

<xsl:output method="xml"
version="1.0"
encoding="windows-1251"
omit-xml-declaration="yes"
indent="yes" />

<xsl:template match="/">
<xsl:text disable-output-escaping="yes"><![CDATA[<?xml version="1.0" encoding="windows-1251" standalone="yes" ?>]]></xsl:text>
<BODY>
<xsl:apply-templates select="/BODY/block1/dokum"></xsl:apply-templates>
</BODY>
</xsl:template>

<xsl:template match="dokum">
<xsl:element name="dokum">
<xsl:apply-templates select="/BODY/block1/dokum/sklad_1"></xsl:apply-templates>
<xsl:apply-templates select="/BODY/block1/dokum/sklad_2"></xsl:apply-templates>
</xsl:element>
</xsl:template>

<xsl:template match="/BODY/block1/dokum/sklad_1">
<xsl:element name="sklad_1_Id">
<xsl:value-of select="/BODY/block1/dokum/sklad_1/tbl_1/tbl_2/tbl_3/id"/>
</xsl:element>
</xsl:template>

<xsl:template match="/BODY/block1/dokum/sklad_2">
<xsl:element name="sklad_2_Id">
<xsl:value-of select="/BODY/block1/dokum/sklad_2/tbl_1/tbl_2/tbl_3/id"/>
</xsl:element>
</xsl:template>
</xsl:stylesheet>

Получается:
?xml version="1.0" encoding="windows-1251" standalone="yes" ?>
<BODY>
<dokum>
<sklad_1_Id>100</sklad_1_Id>
<sklad_1_Id>100</sklad_1_Id>
<sklad_2_Id>200</sklad_2_Id>
<sklad_2_Id>200</sklad_2_Id>
</dokum>
<dokum>
<sklad_1_Id>100</sklad_1_Id>
<sklad_1_Id>100</sklad_1_Id>
<sklad_2_Id>200</sklad_2_Id>
<sklad_2_Id>200</sklad_2_Id>
</dokum>
</BODY>

Пожалуйста, подскажите как это сделать правильно?
Vasilisk
Наставник

Зарегистрирован: 17.05.2006
Сообщения: 370
Откуда: Украина, Харьков
[13569] Вт Фев 17, 2009 23:37

Если нужен ответ, то попробуйте все это оформить с тегом [code] и отступами.
_________________
С уважением Vasilisk
Уважайте читающих, используйте тэги [code ][/code]
svn
Новичок

Зарегистрирован: 17.02.2009
Сообщения: 2

[13574] Ср Фев 18, 2009 07:44

Нужно исходный файл:

Код:

<?xml version="1.0" encoding="windows-1251"?>
<BODY>
  <msg_typ>1</msg_typ>
  <msg_date>01/10/2008</msg_date>
    <block1>
      <dokum>
         <dokum_num>1</dokum_num>
            <sklad_1>
               <tbl_1>
                  <tbl_2>
                     <tbl_3>
                       <id>100</id>
                     </tbl_3>
                  </tbl_2>
               </tbl_1>
            </sklad_1>
            <sklad_2>
               <tbl_1>
                  <tbl_2>
                    <tbl_3>
                      <id>200</id>
                    </tbl_3>
                  </tbl_2>
                </tbl_1>
             </sklad_2>
           </dokum>
           <dokum>
             <dokum_num>2</dokum_num>
               <sklad_1>
                  <tbl_1>
                     <tbl_2>
                        <tbl_3>
                          <id>400</id>
                        </tbl_3>
                     </tbl_2>
                   </tbl_1>
               </sklad_1>
               <sklad_2>
                   <tbl_1>
                     <tbl_2>
                        <tbl_3>
                           <id>400</id>
                        </tbl_3>
                     </tbl_2>
                   </tbl_1>
               </sklad_2>
             </dokum>
           </block1>
       </BODY>



Преобразовать в:

Код:


<BODY>
  <dokum>
     <sklad_1_Id>100</sklad_1_Id>
     <sklad_2_Id>200</sklad_2_Id>
  </dokum>
  <dokum>
     <sklad_1_Id>300</sklad_1_Id>
     <sklad_2_Id>400</sklad_2_Id>
  </dokum>
</BODY>




Делаю:

Код:


<?xml version="1.0" encoding="windows-1251" ?>
<xsl:stylesheet version="1.0"
     xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
     xmlns:msxsl="urn:schemas-microsoft-com:xslt"
     xmlns:xsd="http://www.w3.org/2001/XMLSchema"
     xmlns:msdata="urn:schemas-microsoft-com:xml-msdata"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     exclude-result-prefixes="xsl msxsl xsd msdata xsi">

<xsl:output method="xml"
     version="1.0"
     encoding="windows-1251"
     omit-xml-declaration="yes"
     indent="yes" />

<xsl:template match="/">
     <xsl:text disable-output-escaping="yes"><![CDATA[<?xml version="1.0" encoding="windows-1251" standalone="yes" ?>]]></xsl:text>
     <BODY>
        <xsl:apply-templates select="/BODY/block1/dokum"></xsl:apply-templates>
     </BODY>
</xsl:template>

<xsl:template match="dokum">
   <xsl:element name="dokum">
       <xsl:apply-templates select="/BODY/block1/dokum/sklad_1"></xsl:apply-templates>
       <xsl:apply-templates select="/BODY/block1/dokum/sklad_2"></xsl:apply-templates>
   </xsl:element>
</xsl:template>

<xsl:template match="/BODY/block1/dokum/sklad_1">
   <xsl:element name="sklad_1_Id">
      <xsl:value-of select="/BODY/block1/dokum/sklad_1/tbl_1/tbl_2/tbl_3/id"/>
   </xsl:element>
</xsl:template>

<xsl:template match="/BODY/block1/dokum/sklad_2">
   <xsl:element name="sklad_2_Id">
      <xsl:value-of select="/BODY/block1/dokum/sklad_2/tbl_1/tbl_2/tbl_3/id"/>
   </xsl:element>
</xsl:template>
</xsl:stylesheet>




Получается:

Код:


?xml version="1.0" encoding="windows-1251" standalone="yes" ?>
<BODY>
  <dokum>
    <sklad_1_Id>100</sklad_1_Id>
    <sklad_1_Id>100</sklad_1_Id>
    <sklad_2_Id>200</sklad_2_Id>
    <sklad_2_Id>200</sklad_2_Id>
  </dokum>
  <dokum>
    <sklad_1_Id>100</sklad_1_Id>
    <sklad_1_Id>100</sklad_1_Id>
    <sklad_2_Id>200</sklad_2_Id>
    <sklad_2_Id>200</sklad_2_Id>
  </dokum>
</BODY>

Fireball
Наставник

Зарегистрирован: 26.02.2008
Сообщения: 282

[13578] Ср Фев 18, 2009 17:47

omit-xml-declaration="yes" - здесь пишем "no"
<xsl:text disable-output-escaping="yes"><![CDATA[<?xml version="1.0" encoding="windows-1251" standalone="yes" ?>]]></xsl:text> - это убираем

Дальше, нужно внутри body получить dokum. Так и пишем:

Код:

<xsl:template match="body">
  <xsl:copy><!-- вставляет тэги body -->
    <xsl:apply-templates select="docum" />
  </xsl:copy>
</xsl:template>



Затем внутри dokum нужно получить sklad_#. Так и пишем:

Код:

<xsl:template match="dokum">
  <xsl:copy>
    <xsl:apply-templates select="node()[starts-with(name(), 'sklad')]" />
  </xsl:copy>
</xsl:template>



Внутри sklad нужно получить id и изменить имя ноды, добавив _Id к имени.

Код:

<xsl:template match="node()[starts-with(name(), 'sklad')]">
  <xsl:element name="concat(name(), '_Id'">
    <xsl:apply-templates select=".//id/text()" />
  </xsl:element>
</xsl:template>



Код на работоспособность не проверял, т.е. могут быть опечатки и недомысленности (например, вместо starts-with возможно потребуется использовать contains). Нужны ТОЛЬКО эти три шаблона.