我有一个转换为HTML的ODT文档。该文档具有描述各种字段的特定文本字段。我用它来创建电子邮件。现在我想将它们转换为PHP文档。
字段如下所示:
<p><b>Day #0</b></p>
<p><b>Subject:</b></p>
<p>Here is a subject for Day #0</p>
<p><b>Body</b></p>
<p>A Paragraph One</p>
<p>A Paragraph Two</p>
<p>A Paragraph Three</p>
<p><b>Day #1</b></p>
<p><b>Subject:</b></p>
<p>Here is a subject for Day #1</p>
<p><b>Body</b></p>
<p>B Paragraph One</p>
<p>B Paragraph Two</p>
<p>B Paragraph Three</p>
<p>B Paragraph Four</p>
<p>B Paragraph Five</p>
<p><b>Day #3</b></p>
<p><b>Subject:</b></p>
[...etc...]
在XSTL中,我能够正确提取日期编号和主题。但是,我真的不知道如何提取所有Body段落。
正如我们在上面的示例中所看到的,在某些情况下可能有三个,在其他情况下可能有五个段落......它可以是从一个到无穷大的任何东西(零不是可接受的情况,如果有帮助的话。)
<?xml version="1.0"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="@* | node()">
<xsl:apply-templates select="/html/body/p[starts-with(b, 'Day #')]"/>
</xsl:template>
<!-- Extracting Day #, easy -->
<xsl:template match="*[starts-with(., 'Day #')]">
<xsl:value-of select="substring-after(b, 'Day #')"/><xsl:text disable-output-escaping="yes"> => array(
</xsl:text>
<!-- Extracting Subject, easy -->
<xsl:text disable-output-escaping="yes"> "subject" => "</xsl:text>
<xsl:copy-of select="following-sibling::p[2]/node()"/>
<xsl:text disable-output-escaping="yes">",
"message" =>
<<<EOF</xsl:text>
<!-- Extracting Body, how can I copy all the siblings up to the next Day #? -->
<xsl:copy-of select="following-sibling::p[4], following-sibling::p[5]"/>
<!-- I tried with this but it did not help...
following-sibling::p[4] >> following-sibling::p[4]/b[starts-with(., 'Day #')]"/
-->
<xsl:text>
EOF
),
</xsl:text>
</xsl:template>
</xsl:stylesheet>
预期的输出有一个标题和页脚没有在这里显示,但最后是一个带有子数组数组的PHP脚本。这里的示例展示了我期望在这里展示的XSLT代码:
0 => array(
"subject" => "Here is a subject for Day #0",
"message" =>
<<<EOF
<p>A Paragraph One</p>
<p>A Paragraph Two</p>
<p>A Paragraph Three</p>
EOF
),
1 => array(
"subject" => "Here is a subject for Day #1",
"message" =>
<<<EOF
<p>B Paragraph One</p>
<p>B Paragraph Two</p>
<p>B Paragraph Three</p>
<p>B Paragraph Four</p>
<p>B Paragraph Five</p>
EOF
),
...etc...
请注意,我可以在条目列表的末尾添加逗号(,
)。 PHP允许这样的。但是,最后一个条目后面不会跟"Day #123"
,虽然如果处理这种特殊情况太复杂,很容易在源中再添加一行。
请注意,正文中的段落也可能使用其他标记,例如锚点(<a>
),粗体(<b>
)和斜体(<i>
)。
P.S。我在Ubuntu 16.04上使用Saxon版本9.1.0.8J
答案 0 :(得分:2)
正如我在您的问题的评论中提到的,这是一个分组问题。我相信以下样式表产生的输出非常接近预期的输出:
XSLT 2.0
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8" />
<xsl:template match="/html">
<xsl:for-each-group select="body/p" group-starting-with="p[starts-with(b, 'Day #')]">
<xsl:value-of select="substring-after(b, 'Day #')"/>
<xsl:text> => array( "subject" => "</xsl:text>
<xsl:value-of select="current-group()[3]"/>
<xsl:text>", "message" => <<<EOF </xsl:text>
<xsl:for-each select="current-group()[position() > 4]">
<xsl:text><p></xsl:text>
<xsl:value-of select="."/>
<xsl:text></p> </xsl:text>
</xsl:for-each>
<xsl:text>EOF ), </xsl:text>
</xsl:for-each-group>
</xsl:template>
</xsl:stylesheet>