工作中需要通过xslt将xml转为html,而结果html又需要格式化的<script></script>标签,否则(使用<script/>)加载html会出错。这导致处理<br>标签时也会结队出现:<br></br>。这样会多出一个换行,如:
<!DOCTYPE html>
<html>
<body>
<p>hello<br></br>html</p>
</body>
</html>
应该将xml中的<br>标签转为<br />。
介绍一种转换方法:
void Ctest06072View::OnTest()
{
// TODO: 在此添加命令处理程序代码
MSXML2::IXMLDOMDocumentPtr xmlTree;
HRESULT hr = xmlTree.CreateInstance(__uuidof(MSXML2::DOMDocument60));
if(FAILED(hr))
return;
xmlTree->load("d:\\test.xml");
SaveAsHtml(xmlTree, _T("d:\\test.html"), true);
}
bool Ctest06072View::SaveAsHtml(MSXML2::IXMLDOMDocumentPtr xmlTree, const wchar_t* cszFileName, bool bIndentation /*= true*/)const
{
try
{
if (bIndentation)
{
// Use xslt to indent the output xml
MSXML2::IXMLDOMDocument2Ptr pXSLTIndenter;
_bstr_t bstrXSLTIndenter =
L"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
L"<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n"
L"<xsl:output method=\"html\" version=\"1.0\" indent=\"yes\" encoding=\"utf-8\" omit-xml-declaration=\"yes\" />\n"
L"<xsl:template match=\"@* | node()\">\n"
L" <xsl:choose>\n"
L" <xsl:when test=\"name(.) = 'br'\">\n"
L" <xsl:text disable-output-escaping=\"yes\"><br /></xsl:text>\n"
L" </xsl:when>\n"
L" <xsl:otherwise>\n"
L" <xsl:copy>\n"
L" <xsl:apply-templates select=\"@* | node()\"/>\n"
L" </xsl:copy>\n"
L" </xsl:otherwise>\n"
L" </xsl:choose>\n"
L"</xsl:template>\n"
L"</xsl:stylesheet>\n";
if (FAILED(pXSLTIndenter.CreateInstance(__uuidof(MSXML2::DOMDocument60))))
return false;
if (!pXSLTIndenter->loadXML(bstrXSLTIndenter))
return false;
std::wstring wstrResult = xmlTree->transformNode(pXSLTIndenter);
if (wstrResult.empty())
return false;
// Create another tree to write out the indented xml
MSXML2::IXMLDOMDocumentPtr treeAnother;
HRESULT hr = treeAnother.CreateInstance(__uuidof(MSXML2::DOMDocument60));
if(FAILED(hr))
return false;
if (!treeAnother->loadXML(wstrResult.c_str()))
return false;
Write process instruction
//CXMLElement elementRoot = treeAnother.GetRootElement();
//CXMLPI xmlPI = treeAnother.CreateProcessingInstruction(L"xml", L"version=\"1.0\" encoding=\"utf-8\"");
//treeAnother.InsertChildBefore(xmlPI, elementRoot);
return SUCCEEDED(treeAnother->save(_variant_t(cszFileName)));
}
else
{
return SUCCEEDED(xmlTree->save(_variant_t(cszFileName)));
}
}
catch (_com_error e)
{
return false;
}
}
参考:https://stackoverflow.com/questions/14567794/using-br-tag-within-xml-for-xslt
https://www.oxygenxml.com/forum/topic5818.html
竟然好几个月没写博客了,忘了自己是程序员了。