Javascript JS:基于节点解析XML和更新控件
我在一次采访中被问到这个问题。任务是在客户端解析xml,并用其内容填充html页面。还要求而不是使用jQuery 理想情况下,我甚至不知道XML上有什么,只需为其中的每个节点/元素添加一个标签。但假设我确实知道xml的样子:Javascript JS:基于节点解析XML和更新控件,javascript,asp.net,xml,Javascript,Asp.net,Xml,我在一次采访中被问到这个问题。任务是在客户端解析xml,并用其内容填充html页面。还要求而不是使用jQuery 理想情况下,我甚至不知道XML上有什么,只需为其中的每个节点/元素添加一个标签。但假设我确实知道xml的样子: <?xml version="1.0" encoding="UTF-8"?> <cv> <FirstName>David</FirstName> <LastName>Refaeli</Las
<?xml version="1.0" encoding="UTF-8"?>
<cv>
<FirstName>David</FirstName>
<LastName>Refaeli</LastName>
<Jobs>Worst JS Programmer</Jobs>
</cv>
大卫
拉费里
最差JS程序员
我的服务器端html是:
<body>
<form id="form1" runat="server">
<div>
<asp:TextBox ID="TextBox1" runat="server" Height="185px" Width="279px"></asp:TextBox><br />
<asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="return ParseXml();" /><br />
<br />
<asp:Label ID="FirstName" runat="server" Text=""></asp:Label><br />
<asp:Label ID="LastName" runat="server" Text=""></asp:Label><br />
<asp:Label ID="Jobs" runat="server" Text=""></asp:Label><br />
</div>
</form>
</body>
</html>
让我们假设文本框包含xml。我已经为xml中的文本设置了占位符标签
我试着运行这个JS(以及许多其他变体),但失败了,在VS中调试它似乎找不到原因(它会突然将我放入jQuery文件…),所以我猜我走错了方向
<script>
function ParseXml() {
var text = document.getElementById('<% = TextBox1.ClientID %>');
parser = new DOMParser();
xmlDoc = parser.parseFromString(text.textContent, "text/xml");
var a1 = xmlDoc.getElementsByTagName("cv")[0].childNodes[0].nodeValue;
var a2 = xmlDoc.getElementsByTagName("cv")[0].childNodes[1].nodeValue;
var a3 = xmlDoc.getElementsByTagName("cv")[0].childNodes[2].nodeValue;
document.getElementById('<% = FirstName.ClientID %>').textContent = a1;
document.getElementById('<% = LastName.ClientID %>').textContent = a2;
document.getElementById('<% = Jobs.ClientID %>').textContent = a3;
return true;
}
</script>
函数ParseXml(){
var text=document.getElementById(“”);
parser=新的DOMParser();
xmlDoc=parser.parseFromString(text.textContent,“text/xml”);
var a1=xmlDoc.getElementsByTagName(“cv”)[0]。子节点[0]。节点值;
var a2=xmlDoc.getElementsByTagName(“cv”)[0]。子节点[1]。节点值;
var a3=xmlDoc.getElementsByTagName(“cv”)[0]。子节点[2]。节点值;
document.getElementById(“”).textContent=a1;
document.getElementById(“”).textContent=a2;
document.getElementById(“”).textContent=a3;
返回true;
}
任何帮助都将不胜感激。当函数返回true时,将表单发布到服务器,因此您将获得新表单并丢失所有Javascript更改。第一个更改是返回false以防止回发。然后我改变了从xml检索文本的方式
function ParseXml() {
var xml = document.getElementById('<% = TextBox1.ClientID %>').value;
var parser = new DOMParser();
xmlDoc = parser.parseFromString(xml, "text/xml");
var firstName = xmlDoc.getElementsByTagName("FirstName")[0].childNodes[0].nodeValue;
var lastName = xmlDoc.getElementsByTagName("LastName")[0].childNodes[0].nodeValue;
var jobs = xmlDoc.getElementsByTagName("Jobs")[0].childNodes[0].nodeValue;
document.getElementById('<% = FirstName.ClientID %>').innerText = firstName;
document.getElementById('<% = LastName.ClientID %>').textContent = lastName;
document.getElementById('<% = Jobs.ClientID %>').textContent = jobs;
return false;
};
通过这些更改,代码应该能够像这样解析xml:
var tags = xmlDoc.getElementsByTagName("cv")[0].childNodes;
for (key in tags)
{
if (tags[key].nodeName.length) {
document.body.innerHTML += '<b>'
+ tags[key].nodeName + ':</b> '
+ tags[key].textContent + '<br />';
}
}
<?xml version="1.0" encoding="UTF-8"?>
<cv>
<FirstName>David</FirstName>
<LastName>Refaeli</LastName>
<Jobs>Worst JS Programmer</Jobs>
</cv>
不确定服务器端HTML是否是问题的一部分,但我想不是。 对于概念验证,我将继续使用您的示例XML,并从数据构建文本输入。 表单内容是在AJAX调用后加载页面时动态创建的,因此您必须使用服务器才能看到它的工作情况。所有三个文件应并排放置 HTML页面(index.HTML)
动态形式
一些行动
数据(Data.xml)
大卫
拉费里
有抱负的JS程序员
JavaScript代码(index.js)
//从字符串创建标签并附加到父DOM元素
函数addLabel(父级,名称){
var wrapper=document.createElement('div');
var label=document.createElement('label');
label.innerHTML=名称;
包装器。附加子项(标签);
parent.appendChild(包装器);
}
//使用id和值从创建文本输入
//并附加到父DOM元素
函数addTextbox(父级、id、值){
var box=document.createElement('input');
box.type='text';
box.id=id;
box.value=值;
父.子(框);
}
//为id和值为的文本创建带标签的输入
函数createTextbox(id,值){
var form=document.getElementById('form-content');
addLabel(表格、id);
addTextbox(表单、id、值);
}
//上载用于定义动态文本输入的数据
//表单并创建表单
函数更新(){
var xhr=new XMLHttpRequest();
xhr.onload=函数(){
var值=xhr.responseXML.documentElement.children;
变量长度=value.length;
对于(变量i=0;i
正如您所看到的,输入的解析和创建是分开的。现在,如果我们将XML与实际的输入类型(例如文本、收音机、复选框)联系起来,我们可以扩展代码,根据数据创建不同的输入字段,最终创建一个真正的、纯粹由XML定义的复杂表单。采访者想看看您是否知道如何进行XSLT转换(或者只是想看看你是否知道这个概念) 我在您的原始XML上添加了一个CV列表,并添加了XSLT转换模板,该模板将创建
标题和一个表,该表将输出CV列表-每个CV位于单独的行中,每个属性位于单独的列中。但是,您确实可以按照自己的方式对其进行样式设置
单击按钮时运行的代码将从一个文本区域加载XML对象,从另一个文本区域加载xslt对象。然后,它将使用XSLTProcessor
对象导入xslt样式表,并使用transformToFragment
函数将XML转换为HTML片段,并将该片段放在
元素中
以下是您可以查看的完整片段:
函数转换()
{
var parser=新的DOMParser();
var xml=parser.parseFromString(document.getElementById('xml')。value,'text/xml');
var xslt=parser.parseFromString(document.getElementById('xslt')。value,'text/xml');
var xsltProcessor=new xsltProcessor();
导入样式表(xslt);
resultDocument=xsltProcessor.transformToFragment(xml,文档);
document.getElementById('output').appendChild(resultDocument);
}
XML:
大卫
拉费里
最差JS程序员
伊凡
费里奇
赏金猎人
XSLT:
简历
名字
姓
乔布斯
<?xml version="1.0" encoding="UTF-8"?>
<cv>
<FirstName>David</FirstName>
<LastName>Refaeli</LastName>
<Jobs>Worst JS Programmer</Jobs>
</cv>
xmlDoc.getElementsByTagName("FirstName")[0].childNodes[0].nodeValue;
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body style="margin:50px">
<form>
<h1>Dynamic Form</h1>
<div id="form-content"></div>
<button>some action</button>
</form>
<script src="index.js"></script>
</body>
</html>
<?xml version="1.0" encoding="UTF-8"?>
<cv>
<FirstName>David</FirstName>
<LastName>Refaeli</LastName>
<Jobs>Aspiring JS Programmer</Jobs>
</cv>
// create a label from a string and append to parent DOM element
function addLabel(parent, name) {
var wrapper = document.createElement('div');
var label = document.createElement('label');
label.innerHTML = name;
wrapper.appendChild(label);
parent.appendChild(wrapper);
}
// create a text input from a with id and value
// and append to parent DOM element
function addTextbox(parent, id, value) {
var box = document.createElement('input');
box.type = 'text';
box.id = id;
box.value = value;
parent.appendChild(box);
}
// create a input with label for text with id and value
function createTextbox(id, value) {
var form = document.getElementById('form-content');
addLabel(form, id);
addTextbox(form, id, value);
}
// upload the data that defines dynamic text inputs for a
// form and create the form
function update () {
var xhr = new XMLHttpRequest();
xhr.onload = function () {
var values = xhr.responseXML.documentElement.children;
var length = values.length;
for (var i = 0; i < length; i++) {
var node = values[i];
var name = node.nodeName;
var value = node.innerHTML;
createTextbox(name, value);
};
};
xhr.onerror = function (error) {
console.error(error);
};
xhr.responseType = 'document';
xhr.open('GET', 'data.xml');
xhr.send();
}
// simplistic onload :-)
update();