xml和html之间相互转换

一、xml转换html

xml+xslt是典型的数据与表现分离的设计方式。
当然,你可以直接转换成HTML,但是如果你要进行整体变化的时候,XML+XSLT的优势就体现出来了。
同样的数据,因为你已经有XML,已经不需要再进行一次数据库的访问,只要更换了XSLT,就可以生成新的HTML。
另外,XML+XSLT的性能也是很优秀的。

将内容与内容的表现分离,软件界自从成为一个行业以来一直在追求的目标。
目的在于更加灵活的复用内容。现在先给一个简单的例子:

1. xml文件:catalog.xml


<?xml version="1.0" encoding="ISO-8859-1"?>
<?xml-stylesheet type="text/xsl" href="cdcatalog.xsl"?>
<catalog>
<cd>
<title>Empire Burlesque</title>
<artist>Bob Dylan</artist>
<country>USA</country>
<company>Columbia</company>
<price>10.90</price>
<year>1985</year>
</cd>
</catalog>

2. xsl文件:cdcatalog.xsl


<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
<html>
<body>
<h2>My CD Collection</h2>
<table border="1">
<tr bgcolor="#9acd32">
<th align="left">Title</th>
<th align="left">Artist</th>
<th align="left">Country</th>
<th align="left">Company</th>
<th align="left">Price</th>
<th align="left">Year</th>
</tr>
<xsl:for-each select="catalog/cd">
<tr>
<td><xsl:value-of select="title"/></td>
<td><xsl:value-of select="artist"/></td>
<td><xsl:value-of select="country"/></td>
<td><xsl:value-of select="company"/></td>
<td><xsl:value-of select="price"/></td>
<td><xsl:value-of select="year"/></td>
</tr>
</xsl:for-each>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>

3. 利用浏览器打开该xml文件如下图:

下面简单说下xsl文件一些问题:

1、代码第一行声明XSL文件的编码模式。  
2、代码第二行是正确的声明XSL样式表,可以用xsl:stylesheet也可以用xsl:transform 。
3、代码第三行,声明输出方式是Html,编码方式是utf-8。
4、<xsl:for-each>选取指定的节点集中的每个 XML 元素。
5、<xsl:value-of> 元素用于提取某个选定节点的值,并把值添加到转换的输出流中。
详见:http://www.w3school.com.cn/xsl/index.asp
推荐一款软件可供下载:http://www.ouyaoxiazai.com/download/y11196.html

二、html转换xml

最近在做一些网页信息采集的工作,说通俗点就是爬虫工具,要监控页面中某一部分内容是否发生变化。起初考虑用正则表达式去匹配网页源码,经过咨询有经验人士,推荐使用xpath去获取页面内容能获得更好的效率。但是对于html这种宽松语法要求的语言来说,不可能100%地完全符合xml标准,那么就没法使用xpath,说得更直接点就是:不能把html源码直接加载到xmldocument中。为了使用xpath,只能对html内容进行转换或者规范,于是就写了这么一个方法。

该方法比较地偷懒,借助了开源工具htmlparser获取html源码中的所有节点,然后遍历各个节点,转换为对应的xmlnode。对于html中有未闭合的节点,在转换后实际代码会有一些差别,但是不影响xpath的使用(这也跟如何写xpath的内容有关)。

实现方式如下,需引用htmlparser的dll


/// <summary>
/// 解析Xml文件的帮助类
/// </summary>
public class XMLHelper
{
/// <summary>
/// 有效名称的正则表达式
/// </summary>
static string validName = @"^[^\$\/;""\!#\)\.]+$";

#region CovertHtmlToXml
/// <summary>
/// 转换html源码为xml格式
/// </summary>
/// <param name="html">html源码</param>
/// <returns>xml字符串</returns>
/// <param name="TargetTag">需转换的标记名</param>
public static string CovertHtmlToXml(string html, string targetTag)
{
try
{
XmlDocument doc = new XmlDocument();
XmlNode xmlDeclaration = doc.CreateXmlDeclaration("1.0", "utf-8", null);
doc.AppendChild(xmlDeclaration);

// 借助htmlparser解析html内容
Parser parser = Parser.CreateParser(html, "GBK");
// 筛选出指定的节点
TagNameFilter tnf = new TagNameFilter(targetTag);
NodeList nodes = parser.Parse(tnf);

// 创建根节点
XmlElement root = doc.CreateElement("Tags");

TagNode tagNode = null;
Hashtable ht = null;
XmlAttribute attr = null;
XmlElement parent = null;
for (int i = 0; i < nodes.Size(); i++)
{
tagNode = nodes[i] as TagNode;
parent = doc.CreateElement(tagNode.TagName);

// 添加属性
ht = tagNode.Attributes;
foreach (DictionaryEntry ent in ht)
{
// 查看属性名是否合法
if (Regex.IsMatch(ent.Key.ToString(), validName))
{
attr = doc.CreateAttribute(ent.Key.ToString());
attr.Value = ent.Value.ToString();
parent.Attributes.Append(attr);
}
}// end foreach (DictionaryEntry ent in ht)

AppendChild(tagNode, parent, doc);

root.AppendChild(parent);
}
doc.AppendChild(root);

return doc.OuterXml;

//throw new Exception("给定的html文本必须至少包含一个" + targetTag + "节点");
}
catch (Exception ex)
{
throw new Exception("转换html内容出错:" + ex.Message);
}
}

/// <summary>
/// 添加子节点
/// </summary>
/// <param name="tagNode">Html的父节点</param>
/// <param name="parent">Xml的父节点</param>
/// <param name="doc">Xml文档对象</param>
private static void AppendChild(INode tagNode, XmlNode parent, XmlDocument doc)
{
INode node = null;
XmlNode xmlNode = null;
XmlAttribute attr = null;
Hashtable ht = null;

// 判断是否包含子节点
if (tagNode.Children != null && tagNode.Children.Size() > 0)
{
for (int i = 0; i < tagNode.Children.Size(); i++)
{
node = tagNode.Children[i];
xmlNode = null;
attr = null;
ht = null;

// 如果是html标记节点
if (node is TagNode)
{
TagNode tn = node as TagNode;
if (Regex.IsMatch(tn.TagName, validName))
{
xmlNode = doc.CreateElement(tn.TagName);

// 添加属性
ht = tn.Attributes;
foreach (DictionaryEntry ent in ht)
{
// 查看属性名是否合法
if (Regex.IsMatch(ent.Key.ToString(), validName))
{
attr = doc.CreateAttribute(ent.Key.ToString());
attr.Value = ent.Value.ToString();
xmlNode.Attributes.Append(attr);
}
}
}
}

// 如果是文本节点
if (node is TextNode)
{
xmlNode = doc.CreateTextNode((node as TextNode).ToPlainTextString());
}

if (xmlNode != null)
{
parent.AppendChild(xmlNode);
AppendChild(node, xmlNode, doc);
}
}
}
}
#endregion
}


转自:http://www.cnblogs.com/shenba/archive/2009/04/12/1434050.html

推荐一款软件:http://www.cnblogs.com/shenba/archive/2009/12/19/1627706.html

以上仅供自己学习之用!

 

时间: 2024-10-29 19:09:37

xml和html之间相互转换的相关文章

php中 xml json 数组 之间相互转换

php中 xml json  数组 之间相互转换 1 数组转json $result = array( 'status' =>$status, 'message'=>$message, 'data'=>$data, ); json_encode($result);

WebService(2)-XML系列之Java和Xml之间相互转换

源码下载:链接:http://pan.baidu.com/s/1ntL1a7R 密码: rwp1 本文主要讲述:使用jaxb完成对象和xml之间的转换 TestJava2xml.java如下所示: package com.tgb.jaxb.v1; import java.io.StringReader; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Mar

C++ 中 int,char*,string,CString之间相互转换-整理

#include <string> //使用C++标准库的string类时 using namespace std; //同上 #include <sstream> #include <iostream> #include <stdlib.h> //要将string类和int类型直接转换最好有这些包含, //因为自己写一个转换函数比较方便,函数定义参考如下 string getstring ( const int n ) { std::stringstrea

protobuf,json,xml,binary,Thrift之间的对比

http://blog.csdn.net/angus_17/article/details/8493448 binary 二进制,数据流,也可以转化成 1100011类似的 protobuf 是google的,二进制的数据传输协议,性能比 xml 和 json 号. 但 可读性 差 Thrift 是 FackBook的,性能 比 protobuf还好 一条消息数据,用protobuf序列化后的大小是json的10分之一,xml格式的20分之一,是二进制序列化的10分之一,总体看来ProtoBuf

HTML(DOM)与JavaScript嵌套数组之间相互转换

1. [代码][JavaScript]代码     /*<html><head>  <title>HTML RESTructure</title><style></style><script>*/// workDOM函数遍历目标元素或节点// 有两种模式://   1. `element`模式(默认)(包含所定义的元素项)//   2. `node`模式(包含文本节点在内的所有节点)function walkDOM(mod

Long和Date数据类型之间相互转换代码

static final SimpleDateFormat DATETIME_SEC_STR = new SimpleDateFormat("yyyyMMddHHmmss"); 1.Date转Long Long currStartTime = Long.valueOf(DATETIME_SEC_STR.format(new Date())); System.err.println("LONG1: " + currStartTime); 2.Long转Date Dat

XML与Object之间的互转

private static final String W3C_XML_SCHEMA_NS_URI = "http://www.w3.org/2001/XMLSchema"; /** 将对象转换成xml @param obj 要转成xml的对象 @param xsdPath 标准的xml文件就传null @return xml格式的字符串*/public static String objToXml(Object obj, String xsdPath) throws JAXBExce

xml和bean之间转化

xml和bean之间转化//bean@XmlRootElement(name = "register")br/>@XmlAccessorType(XmlAccessType.PROPERTY)@XmlType(propOrder = {"name","age" })public class User {private String name;private String age;public String getName() {return

XML和实体类之间相互转换(序列化和反序列化)

我们需要在XML与实体类,DataTable,List之间进行转换,下面是XmlUtil类,该类来自网络并稍加修改. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67