提问人:MadeFrame 提问时间:9/28/2023 更新时间:9/28/2023 访问量:51
在 XML 中使用 parse-xml 将 文本 转换为 节点
Using parse-xml to convert text to node in XML
问:
我正在处理来自 Access 数据库的 XML 输出,其中某些节点中的文本需要通过 XSLT 转换为节点本身,然后通过 Adobe FrameMaker 运行以创建出版物。在网上看,我看到了很多对 XSLT 函数的引用,我应该有一个名为 parse-xml(Framemaker 的 XSLT 可以使用 Saxon 9.8),它应该允许我做我正在尝试做的事情。我还没有找到使用此函数的单个示例,而且我仍然对 XSLT 很陌生,以至于我无法想象代码的正确构造。此外,如果您知道基于 Web 的 XSLT 3.0 测试器,那将是一个很大的帮助。我一直在使用 XSLtransform.net 这很棒,但它不支持 XSLT 3.0(至少像 Framemaker 一样通过 Saxon 9.8)。
我的XML我需要转换:
<?xml version="1.0" encoding="UTF-8"?>
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata" generated="2023-09-26T10:37:15">
<TEQuery>
<IntID>PR090F</IntID>
<TEName>Exempt Lease From Taxable Owner</TEName>
<Description>
<div><font face="Times New Roman" color=black>&nbsp;Leased properties that qualify for this exemption are reported under one of the following expenditures: </font></div>
<ul>
<ul>
<ul>
<ul>
<ul>
<ul>
<ul>
<li><font face="Times New Roman" color=black>PR001F, </font></li>
<li><font face="Times New Roman" color=black>PR007F,</font></li>
<li><font face="Times New Roman" color=black>PR079F, </font></li>
<li><font face="Times New Roman" color=black>PR083F, </font></li>
<li><font face="Times New Roman" color=black>PR085F, </font></li>
<li><font face="Times New Roman" color=black>PR086F, </font></li>
</ul>
</ul>
</ul>
</ul>
</ul>
</ul>
</ul>
</Description>
<TaxSort>2</TaxSort>
</TEQuery>
</dataroot>
我想要的输出如下:
<dataroot xmlns:od="urn:schemas-microsoft-com:officedata"
generated="2023-09-26T10:37:15">
<TaxExpenditure id="PR090F" TAXSORT="2">Exempt Lease From Taxable Owner
<Description>
<div><font face="Times New Roman" color=black>&nbsp;Leased properties that qualify for this exemption are reported under one of the following expenditures: </font></div>
<unorderedlist>
<listitem>;<font face="Times New Roman" color=black>PR001F, </font></listitem>
<listitem>;<font face="Times New Roman" color=black>PR007F, </font></listitem>
<listitem><font face="Times New Roman" color=black>PR079F, </font></listitem>
<listitem><font face="Times New Roman" color=black>PR083F, </font></listitem>
<listitem><font face="Times New Roman" color=black>PR085F, </font></listitem>
<listitem><font face="Times New Roman" color=black>PR086F, </font></listitem>
</unorderedlist>
</TaxExpenditure>
</dataroot>
这是我当前的 XSL 代码,除了将列表字符串转换为节点之外,它可以做到目前为止的所有事情,但我 100% 迷失了 parse-xml 函数的后续步骤,无论它应该驻留在 xsl:template 语句中还是其他东西,等等。在删除“<字体...”时可以提供的任何帮助通过 xslt 的文本的“<div>”部分也将不胜感激,尽管我怀疑我可能需要在 xslt 之外的过程中稍后执行此操作,或者在删除它们之前将它们也转换为节点。
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" omit-xml-declaration="yes" encoding="UTF-8" indent="yes" />
<xsl:template match="/ | @* | node()">
<xsl:copy>
<xsl:apply-templates select="@* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="TEQuery">
<TaxExpenditure>
<xsl:attribute name="id" select="IntID"/>
<xsl:attribute name="TAXSORT" select="TaxSort"/>
<xsl:value-of select = "TEName"/>
<xsl:apply-templates select="@* | node()" />
</TaxExpenditure>
</xsl:template>
<xsl:template match="IntID"/>
<xsl:template match="TaxSort"/>
<xsl:template match="TEName"/>
</xsl:stylesheet>
答:
正如我在评论中指出的那样,根据 XML 规则,元素的内容格式不正确,因为至少有一些属性值没有正确用引号字符分隔。Description
因此,既不能也不能成功解析该内容。parse-xml
parse-xml-fragment
检查您在 Framemaker 中的 Saxon 版本/版本是否是商业版本(即 PE 或 EE),然后您可以使用(取决于确切的版本)扩展函数 https://www.saxonica.com/html/documentation10/functions/saxon/parse-html.html 或新的 XPath 4 。saxon:parse-html
fn:parse-html
另一方面,在纯 XSLT 2 中有一个不错的小 HTML 标签汤解析器实现,即 David Carlisle 的 https://github.com/davidcarlisle/web-xslt/blob/main/htmlparse/htmlparse.xsl,您可以导入然后像(假设命名空间声明)一样使用它,例如xmlns:dc="data:,dpc"
<xsl:import href="https://raw.githubusercontent.com/davidcarlisle/web-xslt/main/htmlparse/htmlparse.xsl"/>
<xsl:template match="Description">
<xsl:copy>
<xsl:apply-templates select="dc:htmlparse(., '', true())"/>
</xsl:copy>
</xsl:template>
然后你基本上将HTML作为XDM节点(例如,,,元素节点),您可以添加模板来转换它们,例如div
font
ul
li
<xsl:template match="li">
<listitem>
<xsl:apply-templates/>
</listitem>
</xsl:template>
目前尚不清楚您是否真的想要一些结果元素,例如 but then inside again 转义标记;当然,您可以序列化节点,尽管这将在解析它们之后,并使用 XSLT 允许和 Saxon 实现的序列化(例如,可能在属性值周围使用引号),这意味着不可能保留原始转义标记。listitem
fn:serialize
至于在浏览器中摆弄 XSLT 3,https://martin-honnen.github.io/xslt3fiddle/ 使用 SaxonJS(目前为 2.5)(您的示例和我的 XSLT 建议),然后我 https://xsltfiddle.liberty-development.net/ 有 Saxon 10,https://xsltfiddle-beta.liberty-development.net/ 有各种 Saxon 版本。
请记住,https://xsltfiddle.liberty-development.net/ 允许您将小提琴存储在数据库中,但随后您可以与网络共享它们,因此请确保不要保存任何包含私有输入数据或要保密的代码的内容。
评论
saxon:parse-html
评论
Description
<div><font face="Times New Roman" color=black
color