Всем добрый день. Народ, помогите кто может, никогда не работал с XSLT и тут пришлось... Я хочу преобразовать контент из FCK редактора в WordML. Сложного ничего нет, но запнулся на самом простом - XSLTProcessor. У меня есть класс, в котором метод, принимающий контент от FCK редактора и возвращающий результат: Код (Text): <?php class MY_HTML_TO_DOC { function Generate($xmlData) { $xml = new DOMDocument; $xml->loadXML("<div id='mainXMLDiv'>".$xmlData."</div>"); $xsl = new DOMDocument; $xsl->load('mytranslator.xsl'); // Configure the transformer $proc = new XSLTProcessor; $proc->importStyleSheet($xsl); return $proc->transformToXML($xml); } } ?> Для простоты, переменная $xmlData равна "<u>HELLO</u>" А вот непосредственно и сам XSLT файл: Код (Text): <?xml version="1.0" encoding="windows-1251"?> <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp " "> <!ENTITY copy "©"> <!ENTITY reg "®"> <!ENTITY trade "™"> <!ENTITY mdash "—"> <!ENTITY ldquo "“"> <!ENTITY rdquo "”"> <!ENTITY pound "£"> <!ENTITY yen "¥"> <!ENTITY euro "?"> ]> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:v="urn:schemas-microsoft-com:vml"> <xsl:output method="html" encoding="windows-1251" doctype-public="-//W3C//DTD XHTML 1.0 Transitional//EN" doctype-system="http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"/> <xsl:template match="/"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"/> <title> <xsl:apply-templates select="w:wordDocument/o:DocumentProperties"/> </title> </head> <body> <xsl:apply-templates select="w:wordDocument/w:body/wx:sect"/> </body> </html> </xsl:template> <xsl:template match="w:wordDocument/o:DocumentProperties"> <xsl:value-of select="o:Title"/> </xsl:template> <xsl:template match="w:wordDocument/w:body/wx:sect"> <xsl:apply-templates /> </xsl:template> <!-- HEADINGS and PARA --> <xsl:template match="w:p"> <xsl:choose> <xsl:when test="w:pPr/w:pStyle/@w:val=1"> <h1> <xsl:apply-templates select="w:r | w:hlink" /> </h1> </xsl:when> <xsl:when test="w:pPr/w:pStyle/@w:val=2"> <h2> <xsl:apply-templates select="w:r | w:hlink" /> </h2> </xsl:when> <xsl:when test="w:pPr/w:pStyle/@w:val=3"> <h3> <xsl:apply-templates select="w:r | w:hlink" /> </h3> </xsl:when> <xsl:otherwise> <p> <xsl:apply-templates select="w:r | w:hlink" /> </p> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- Simple formatting (bold, italic, underline), images --> <xsl:template match="w:r"> <xsl:choose> <xsl:when test="w:rPr/w:b"><b><xsl:value-of select="w:t" /></b></xsl:when> <xsl:when test="w:rPr/w:u"><u><xsl:value-of select="w:t" /></u></xsl:when> <xsl:when test="w:rPr/w:i"><i><xsl:value-of select="w:t" /></i></xsl:when> <xsl:otherwise><xsl:value-of select="w:t" /></xsl:otherwise> </xsl:choose> </xsl:template> <!-- Parse hyperlinks --> <xsl:template match="w:hlink"> <a href="{@w:dest}"><xsl:value-of select="w:r/w:t" /></a> </xsl:template> <!-- Parse table (colspan supported, no rowspans) --> <xsl:template match="w:tbl"> <table width="100%" cellpadding="0" cellspacing="0" border="1"> <xsl:for-each select="w:tr"> <tr> <xsl:for-each select="w:tc/w:p"> <xsl:if test="../w:tcPr/w:gridSpan/@w:val > 0"> <xsl:text disable-output-escaping="yes"><td colspan=</xsl:text> <xsl:value-of select="../w:tcPr/w:gridSpan/@w:val" /><xsl:text disable-output-escaping="yes">"></xsl:text> </xsl:if> <xsl:if test="not(../w:tcPr/w:gridSpan/@w:val)"> <xsl:text disable-output-escaping="yes"><td></xsl:text> </xsl:if> <xsl:apply-templates select="w:r" /> <xsl:text disable-output-escaping="yes"></td></xsl:text> </xsl:for-each> </tr> </xsl:for-each> </table> </xsl:template> </xsl:stylesheet> Свой класс я использую так: Код (Text): $mhtd = new MY_HTML_TO_DOC(); $transformed = $mhtd->Generate($resumeHTML); $fd = fopen('test.doc','w+'); fwrite($fd,$transformed); fclose($fd); В итоге создается файл test.doc и содержит такой контент: Код (Text): <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns:w="http://schemas.microsoft.com/office/word/2003/wordml" xmlns:wx="http://schemas.microsoft.com/office/word/2003/auxHint" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:aml="http://schemas.microsoft.com/aml/2001/core" xmlns:v="urn:schemas-microsoft-com:vml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=windows-1251"> <title></title> </head> <body></body> </html> Т.е.: XSLTProcessor свою работу делает, но частично, не обрабатывая <U> теги... Народ, подскажите пожалуйста, а почему так происходит? Заранее очень благодарю!
Потому что в приведенном xsl-е нет обработчика тегов u. Есть обработчик корневого тега - он выводится.
Большое спасибо за ответ, Алекс. А разве следующая строка не обрабатывает теги <u>?: Код (Text): <xsl:when test="w:rPr/w:u"><u><xsl:value-of select="w:t" /></u></xsl:when> я нашел данный xsl не помню где, но человек утверждал, что он работает прекрасно.... не понимаю((
e-v-g-e-n-y Сорри, не увидел эту строчку. Она обрабатывает теги <u> с неймспейсом "w", т.е. $xmlData должна быть равна "<w:u>HELLO</w:u>".
Во-первых, надо понять как делается преобразование. Все идет строго по иерархии. Как правило, первым определяется шаблон для корневого тега: Код (Text): <xsl:template match="/"> Внутри это шаблона инициализируются преобразования тегов: w:wordDocument/oocumentProperties и w:wordDocument/w:body/wx:sect: Код (Text): <xsl:apply-templates select="w:wordDocument/o:DocumentProperties"/> <xsl:apply-templates select="w:wordDocument/w:body/wx:sect"/> А из этого следует, что данное преобразование понимает следующую структуру документа: структура исходного документа должна начинаться с корневого тега w:wordDocument, который в свою очередь может содержать теги oocumentProperties и w:body. Причем w:body может содержать в себе теги wx:sect. Все это вовсе не значит, что в документе не может быть других тегов, а значит, что преобразование понимает только их. Дальше смотрим преобразование w:wordDocument/oocumentProperties: Код (Text): <xsl:template match="w:wordDocument/o:DocumentProperties"> <xsl:value-of select="o:Title"/> </xsl:template> Здесь берется значение тега o:Title, являющегося вложенным в тег oocumentProperties. Аналогично нужно посмотреть как развертывается w:wordDocument/w:body/wx:sect.
Алекс, огромное Вам спасибо! Я понял главное - что этот xsl для преобразования WordML в HTML, а я от него ожидал обратного эфекта (из HTML в WordML). Сам алгоритм не сложен, но туториал обязательно почитаю. Еще раз спасибо Вам!