我有这个 html,我想将其解析为多个部分并插入到 SQLite 数据库中:
<html lang="en">
<head>
<title>Title</title>
</head>
<body data-ret-date="2023-08-04">
<h1 data-toc="1" data-callcode="Title1">Title 1—General</h1>
<h2 data-toc="5" data-callcode="Title1Part1">PART 1—DEFINITIONS</h2>
<h3 data-toc="9" data-callcode="Title1Part1Sec1">§ 1 Definitions.</h3>
<p>foo</p>
<p>foo</p>
<h3 data-toc="9" data-callcode="Title1Part1Sec1.1">§ 1.1 Foo.</h3>
<p>foo</p>
<p>foo</p>
<h2 data-toc="5" data-callcode="Title1Part2">PART 2—THE COMMITTEE</h2>
<p>foo</p>
<p>foo</p>
<h3 data-toc="9" data-callcode="Title1Part2Sec2">§ 2 Definitions.</h3>
<p>foo</p>
<p>foo</p>
<h3 data-toc="9" data-callcode="Title1Part2Sec2.1">§ 2.1 Foo.</h3>
<p>foo</p>
<p>foo</p>
<h2 data-toc="5" data-callcode="Title1Part3">PART 3—THE COUNCIL</h2>
<p>foo</p>
<p>foo</p>
<h3 data-toc="9" data-callcode="Title1Part3Sec3">§ 3 Definitions.</h3>
<p>foo</p>
<p>foo</p>
<h3 data-toc="9" data-callcode="Title1Part3Sec3.1">§ 3.1 Foo.</h3>
<p>foo</p>
<p>foo</p>
</body>
</html>
我有这个功能样式表:
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:sql="http://saxon.sf.net/sql"
extension-element-prefixes="sql"
exclude-result-prefixes="xs">
<xsl:variable name="driver" select="'org.sqlite.JDBC'"/>
<xsl:variable name="database" select="'jdbc:sqlite:/home/paul/topics/text.sqlite'"/>
<xsl:output method="xhtml" omit-xml-declaration="yes" encoding="UTF-8" indent="no"/>
<xsl:strip-space elements="*"/>
<xsl:template match="@* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="html">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="head"/>
<xsl:template match="body">
<xsl:variable name="rdate" select="/html/body/@data-ret-date"/>
<xsl:if test="not(element-available('sql:connect'))">
<xsl:message>sql:connect is not available</xsl:message>
</xsl:if>
<xsl:message>Connecting to <xsl:value-of select="$database"/>...</xsl:message>
<xsl:variable name="connection" as="java:java.sql.Connection"
xmlns:java="http://saxon.sf.net/java-type">
<sql:connect driver="{$driver}" database="{$database}">
<xsl:fallback>
<xsl:message terminate="yes">SQL extensions are not installed</xsl:message>
</xsl:fallback>
</sql:connect>
<xsl:message>Connected...</xsl:message>
</xsl:variable>
<xsl:for-each-group select="*" group-starting-with="*[@data-toc]">
<xsl:variable name="text">
<xsl:apply-templates select="current-group()"/>
</xsl:variable>
<sql:insert connection="$connection" table="textt">
<sql:column name="callcode" select="@data-callcode"/>
<sql:column name="text_id" select="0"/>
<sql:column name="child_of" select="0"/>
<sql:column name="rdate" select="$rdate"/>
<sql:column name="txt_string" select="$text"/>
</sql:insert>
</xsl:for-each-group>
<sql:close connection="$connection"/>
<xsl:message>Connection closed..</xsl:message>
</xsl:template>
<!-- transform with Oxygen 17, Saxon 9.6 PE, and the following config file
<configuration xmlns="http://saxon.sf.net/ns/configuration" edition="EE">
<global allowExternalFunctions="true" versionOfXml="1.0"/>
<xslt>
<extensionElement namespace="http://saxon.sf.net/sql"
factory="net.sf.saxon.option.sql.SQLElementFactory"/>
</xslt>
</configuration>
-->
</xsl:stylesheet>
最终的结果是部分成功的。行以纯文本形式插入,但 HTML 被剥离,它在连接中丢失。我希望
txt_string
的 SQL 列包含文本和 HTML。我知道变量 $text
包含 HTML,但它丢失了。
不知道有没有什么可以做的。我可能不应该在此工作流程中使用 SQLite。我可能必须尝试 XML 数据库,例如 ExistDB 或 BerkeleyDB。
(我尝试制作文本 CSV 文件和文本 SQL 脚本文件,但转义引号、逗号和换行符的解决方法是站不住脚的)
$text
不包含“HTML”,它包含解析 HTML 所产生的节点树。一般来说,如果您在需要字符串的上下文中使用节点,您将获得该节点的字符串值,而不是序列化为 XML 或 HTML。
正如 Martin 所说,您需要将节点树序列化为 HTML(或 XHTML、XML)并将序列化形式写入数据库。根据您的处理器版本,您可以使用 saxon:serialize 或 fn:serialize 来执行此操作。您可能需要迁移到更高版本的 Oxygen,其中包括更高版本的 Saxon。