Javascript JS:基于节点解析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,并用其内容填充html页面。还要求而不是使用jQuery

理想情况下,我甚至不知道XML上有什么,只需为其中的每个节点/元素添加一个标签。但假设我确实知道xml的样子:

<?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();