使用XSLT&amp ;;将XML结构转换为另一种XML。 PHP

时间:2013-02-07 19:51:53

标签: php xml xslt

我将通过从那里获取一些数据将this xml文件的结构转换为另一个(具有新元素名称),即:

  1. 所有元素的价值;
  2. 所有元素的元素和元素的元素;
  3. 我刚开始玩XSLT并且知识匮乏,所以不要严格判断我。我的 transform.xsl 模板是(不打印xml元素名称):

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" />
        <xsl:template match="/">
            <xsl:apply-templates select="/RESPONSE/MULTIPLE/SINGLE/KEY" />
        </xsl:template>
    
        <!-- transformation to another xml file -->
        <xsl:template match="/MULTIPLE">
        <course>
        <xsl:for-each select="SINGLE">
            <topic>
                <!-- Updated -->
                <chapter><xsl:value-of select="KEY[@name='name']/VALUE" /></chapter>
                <xsl:for-each select="KEY[@name='modules']/MULTIPLE/SINGLE">
                    <title><xsl:value-of select="KEY[@name='name']/VALUE" /></title>
                    <content><xsl:value-of select="KEY[@name='description']/VALUE" /></content>
                </xsl:for-each>
                <!-- /Updated -->
            </topic>
        </xsl:for-each>
        </course>
    </xsl:template>
    

    预期结构是[更新]:

    <?xml version="1.0" encoding="UTF-8"?>
    <course>
        <topic>
            <chapter>Chapter Name 1</chapter>
            <title>Title Name 1</title>
            <content>Content 1</content>
        </topic>
        <!-- Updated -->
        <topic>
            <chapter>Chapter Name 1</chapter>    <!-- print for each <title> and <content> -->
            <title>Title Name 2</title>
            <content>Content 2</content>
        </topic>
        <topic>
            <chapter>Chapter Name n</chapter>
            <title>Title Name n</title>
            <content>Content n</content>
        </topic>
        <!-- Updated -->
        ...
    </course>
    

    php 程序:

    $xml = new DOMDocument;
    $xml->load("http://dl.dropbox.com/u/72519118/response.xml");
    
    $xsl = new DOMDocument;
    $xsl->load("transform.xsl");
    
    // Configure the transformer
    $proc = new XSLTProcessor;
    $proc->importStyleSheet($xsl);
    
    echo $proc->transformToXML($xml);
    

    任何帮助都将不胜感激。

1 个答案:

答案 0 :(得分:1)

感谢您提出的问题。你走在正确的轨道上,但有一些问题:

由于您要将模板应用于顶级倍数,因此您的第一个apply-templates应如下所示:

<xsl:apply-templates select="/RESPONSE/MULTIPLE" />

由于MULTIPLE不是根元素,如果匹配元素值以斜杠开头,则第二个模板将不匹配任何内容。这是你应该使用的:

<xsl:template match="MULTIPLE">

当你想要比较某些东西(属性,元素等)与字符串值时,你需要在值周围加上引号:

<xsl:value-of select="KEY[@name = 'name']/VALUE" />

修复这些元素后,您将获得此XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" />
  <xsl:template match="/">
    <xsl:apply-templates select="/RESPONSE/MULTIPLE" />
  </xsl:template>

  <!-- transformation to another xml file -->
  <xsl:template match="MULTIPLE">
    <course>
      <xsl:for-each select="SINGLE">
        <topic>
          <chapter>
            <xsl:value-of select="KEY[@name = 'name']/VALUE" />
          </chapter>
          <title>
            <xsl:value-of 
                select="KEY[@name= 'modules']/MULTIPLE/SINGLE/KEY
                                       [@name = 'name']/VALUE" />
          </title>
          <content>
            <xsl:value-of 
                select="KEY[@name= 'modules']/MULTIPLE/SINGLE/KEY
                                 [@name ='description']/VALUE" />
          </content>
        </topic>
      </xsl:for-each>
    </course>
  </xsl:template>
</xsl:stylesheet>

这是一个更新版本,以满足您澄清的要求:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output method="xml" />
  <xsl:template match="/">
    <course>
      <xsl:apply-templates 
         select="/RESPONSE/MULTIPLE/SINGLE/KEY[@name = 'modules']/MULTIPLE/SINGLE" />
    </course>
  </xsl:template>

  <xsl:template match="SINGLE">
    <topic>
      <chapter>
        <xsl:value-of select="../../../KEY[@name = 'name']/VALUE" />
      </chapter>
      <title>
        <xsl:value-of select="KEY[@name = 'name']/VALUE" />
      </title>
      <content>
        <xsl:value-of select="KEY[@name ='description']/VALUE" />
      </content>
    </topic>
  </xsl:template>
</xsl:stylesheet>

请注意,这只是将模板应用于所有第二级<SINGLE>。为了获取章节名称,它会向后移动XML树以从父节点获取该值。

在源XML上运行时的输出是:

<course>
  <topic>
    <chapter>General</chapter>
    <title>News forum</title>
    <content></content>
  </topic>
  <topic>
    <chapter>ANATOMIE</chapter>
    <title>1.1 Die Haut</title>
    <content>
      &lt;div class="no-overflow"&gt;&lt;p&gt;&lt;span class="nolink"&gt;&lt;img src="http://localhost/pluginfile.php/22/mod_page/intro/die_haut.png" width="auto" style="border: 1px       [SNIP]
    </content>
  </topic>
  <topic>
    <chapter>ANATOMIE</chapter>
    <title>1.2 Der Schädel Page</title>
    <content>
      &lt;div class="no-overflow"&gt;&lt;h3&gt;1.2 Der Schädel&lt;/h3&gt;
      [SNIP]
    </content>
  </topic>
  <topic>
    <chapter>ANATOMIE</chapter>
    <title>1.6 Die Regelkreise</title>
    <content>
      &lt;div class="no-overflow"&gt;&lt;h3&gt;1.6 Die Regelkreise&lt;/h3&gt;
      [SNIP]
    </content>
  </topic>
  <topic>
    <chapter>ANATOMIE</chapter>
    <title>Media</title>
    <content></content>
  </topic>
  <topic>
    <chapter>NOTFÄLLE</chapter>
    <title>2.1 Neurologische Notfälle</title>
    <content></content>
  </topic>
  <topic>
    <chapter>NOTFÄLLE</chapter>
    <title>2.5 Krampfanfälle</title>
    <content></content>
  </topic>
  <topic>
    <chapter>NOTFÄLLE</chapter>
    <title>2.9 Pulmonale Notfälle</title>
    <content></content>
  </topic>
  <topic>
    <chapter>STÖRUNGEN</chapter>
    <title>3.1 Störungen der Lebensfunktionen bei Erwachsenen (ab der Pubertät)</title>
    <content></content>
  </topic>
  <topic>
    <chapter>STÖRUNGEN</chapter>
    <title>3.16 Störungen der Lebensfunktionen bei Säuglingen (bis ein Jahr) und Kindern (bis zur Pubertät)</title>
    <content></content>
  </topic>
  <topic>
    <chapter>STÖRUNGEN</chapter>
    <title>3.25 Starke Blutung</title>
    <content></content>
  </topic>
</course>