MarkLogic 8中xdmp.tidy()误删article标签的解决办法及替代方案
The issue here is that the underlying HTML Tidy library used by xdmp.tidy() in MarkLogic 8 doesn’t recognize HTML5 elements like <article> by default—so it strips them as "invalid" tags. Here’s how to fix it:
Preserve tags with Tidy configuration
You can pass a custom Tidy configuration to xdmp.tidy() to explicitly mark <article> as a valid block-level element, and enable HTML5 mode. Here’s an example in XQuery:
let $html := "<article><h1>Hello</h1><p>Some content</p></article>" let $tidy-config := "<config> <new-blocklevel-tags>article</new-blocklevel-tags> <doctype>html5</doctype> <output-xhtml>yes</output-xhtml> </config>" return xdmp:tidy($html, $tidy-config)
Key options explained:
new-blocklevel-tags: Tells Tidy to treat<article>as a valid block-level tag (similar to<div>or<section>), so it won’t strip it.doctype: html5: Enables HTML5 parsing rules, which helps Tidy recognize more modern elements natively.output-xhtml: yes: Ensures the output is well-formed XHTML, which is what you’re targeting.
If you prefer a string-based config instead of XML, you can write it like this:
let $tidy-config := "new-blocklevel-tags: article doctype: html5 output-xhtml: yes" return xdmp:tidy($html, $tidy-config)
Alternative HTML-to-XHTML conversion methods
If you run into limitations with Tidy, here are two reliable alternatives in MarkLogic 8:
1. Use xdmp:html-parse + xdmp:serialize
xdmp:html-parse parses HTML into a node tree, and you can then serialize that tree to XHTML using xdmp:serialize with the xhtml method. This approach often preserves HTML5 elements better in older MarkLogic versions:
let $html := "<article>My content</article>" let $parsed-html := xdmp:html-parse($html) return xdmp:serialize($parsed-html, <options xmlns="xdmp:serialize"> <method>xhtml</method> <indent>yes</indent> <omit-xml-declaration>no</omit-xml-declaration> </options> )
2. Custom XSLT transformation
You can write an XSLT stylesheet that converts HTML to XHTML while preserving all elements. Here’s a minimal example:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="xhtml" indent="yes" encoding="UTF-8"/> <!-- Copy all elements and attributes --> <xsl:template match="@*|node()"> <xsl:copy> <xsl:apply-templates select="@*|node()"/> </xsl:copy> </xsl:template> <!-- Convert HTML attributes to XHTML-compliant ones if needed (e.g., "align" to inline style) --> <xsl:template match="@align"> <xsl:attribute name="style">text-align:<xsl:value-of select="."/>;</xsl:attribute> </xsl:template> </xsl:stylesheet>
Invoke it in XQuery like this:
let $html := "<article align='center'>Centered content</article>" let $xslt := xdmp:document-get("/path/to/your/stylesheet.xsl") return xdmp:xslt-invoke($xslt, xdmp:html-parse($html))
This gives you full control over the conversion process, including which elements to preserve or modify.
内容的提问来源于stack exchange,提问作者Pavan Sky

