我正在尝试将处理指令节点添加到现有XML文档,以便在浏览器中显示时对文档应用XSL转换。我查找了如何使用libxml++
类但无法找到它,所以我尝试使用libxml2
。这就是我想出的:
xmlpp::Document* Doc = Parser->get_document();
// Set processing instruction for stylesheet
const xmlNodePtr PINode = xmlNewDocPI(
Doc->cobj(),
reinterpret_cast<xmlChar*>("xml-stylesheet"),
reinterpret_cast<xmlChar*>("href=\"../stylesheet.xslt\" type=\"text/xsl\"")
);
if (PINode == NULL) {
// Never get here
}
Doc->write_to_file_formatted("mydoc.xml", "utf-8");
处理指令节点未写入文档。那我在这里错过了什么?
答案 0 :(得分:3)
事实证明,仅仅调用xmlNewDocPI
是不够的。它创建处理指令节点并以某种方式将其与文档相关联,但实际上并未将其附加到文档。
为此目的,必须调用一些xmlAdd*
函数,因为我需要将PI包含在XML声明的正下方而不是嵌套在文档根节点中,所以我必须使用以下内容: / p>
xmlAddPrevSibling(Doc->get_root_node()->cobj(), PINode);
它看起来有点hackish但有效。因此,工作代码的完整代码段如下所示:
xmlpp::Document* Doc = Parser->get_document();
// Set processing instruction for stylesheet
const xmlNodePtr PINode = xmlNewDocPI(
Doc->cobj(),
reinterpret_cast<xmlChar*>("xml-stylesheet"),
reinterpret_cast<xmlChar*>("href=\"../stylesheet.xslt\" type=\"text/xsl\"")
);
if (PINode != NULL) {
xmlAddPrevSibling(Doc->get_root_node()->cobj(), PINode);
}
Doc->write_to_file_formatted("mydoc.xml", "utf-8");
答案 1 :(得分:1)
向XML文档添加处理指令可以在纯XSLT中完成:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:strip-space elements="*"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="/">
<xsl:processing-instruction name="xml-stylesheet">
<xsl:text>href="../stylesheet.xslt" type="text/xsl"</xsl:text>
</xsl:processing-instruction>
<xsl:text>
</xsl:text>
<xsl:apply-templates/>
</xsl:template>
</xsl:stylesheet>
将此转换应用于任何XML文档时,如下所示:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
生成了想要的结果:
<?xml-stylesheet href="../stylesheet.xslt" type="text/xsl"?>
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>