使用libxml ++向现有XML文档添加处理指令

时间:2012-01-18 10:07:01

标签: c++ xml libxml2

我正在尝试将处理指令节点添加到现有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");

处理指令节点未写入文档。那我在这里错过了什么?

2 个答案:

答案 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>&#xA;</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>