如何使用 Javascript 在 HTML 文件中显示 XML 内容

Posted

技术标签:

【中文标题】如何使用 Javascript 在 HTML 文件中显示 XML 内容【英文标题】:How to display XML content in HTML file with Javascript 【发布时间】:2020-06-22 07:38:26 【问题描述】:

这是我的 xml 代码。我想用 javascripthtml 页面中显示内容。

<businesses>
    <business bfsId="" id="41481">
        <advertHeader>Welding Supplies, Equipment and Service Business</advertHeader>
        <Price>265000</Price>
        <catalogueDescription>Extremely profitable (Sales £500k, GP £182k) business</catalogueDescription>
        <keyfeature1>
        Well established 25 year business with excellent trading record
        </keyfeature1>
        <keyfeature2>
        Consistently high levels of turnover and profitability over last 5 years
        </keyfeature2>
    </business>
    <business bfsId="" id="42701">
        <broker bfsRef="1771" ref="003">Birmingham South, Wolverhampton &amp; West Midlands</broker>
        <tenure>freehold</tenure>
        <advertHeader>Prestigious Serviced Office Business</advertHeader>
        <Price>1200000</Price>
        <reasonForSale>This is a genuine retirement sale.</reasonForSale>
        <turnoverperiod>Annual</turnoverperiod>
        <established>28</established>
        <catalogueDescription>This well-located and long-established serviced office</catalogueDescription>
        <underOffer>No</underOffer>
        <image1>https://www.business-partnership.com/uploads/business/businessimg15977.jpg</image1>
        <keyfeature1>other connections</keyfeature1>
        <keyfeature2> Investment Opportunity</keyfeature2>
        <keyfeature3>Over 6,000 sq.ft.</keyfeature3>
        <keyfeature4>Well-maintained </keyfeature4>
        <keyfeature5>In-house services &amp; IT provided</keyfeature5>
    </business>
</businesses>

这是原始的xml文件https://alpha.business-sale.com/bfs.xml我只是用了一小部分来描述情况。

要求

为每个&lt;business&gt; 元素打印一行 为每个&lt;business&gt; 选择一些特定的子元素并仅为这些元素打印列。(不是全部)。对于这种情况下的示例,我只想打印 &lt;advertHeader&gt; 的值; &lt;Price&gt;&lt;description&gt; 并想忽略其他元素。 仅打印 &lt;business&gt; 的行,其中 &lt;Price&gt; 的值 > 10000 。如果小于 10000 则不打印该行 每 10 行后分页

这是html表格

<table id="MainTable"><tbody id="BodyRows"></tbody></table>

这是我尝试过的 javascript 代码。

window.addEventListener("load", function() 
            getRows();
        );

        function getRows() 
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.open("get", "2l.xml", true);
            xmlhttp.onreadystatechange = function() 
                if (this.readyState == 4 && this.status == 200) 
                    showResult(this);
                
            ;
            xmlhttp.send(null);
        

        function showResult(xmlhttp) 
            var xmlDoc = xmlhttp.responseXML.documentElement;
            removeWhitespace(xmlDoc);
            var outputResult = document.getElementById("BodyRows");
            var rowData = xmlDoc.getElementsByTagName("business");

            addTableRowsFromXmlDoc(rowData,outputResult);
        

        function addTableRowsFromXmlDoc(xmlNodes,tableNode) 
            var theTable = tableNode.parentNode;
            var newRow, newCell, i;
            console.log ("Number of nodes: " + xmlNodes.length);
            for (i=0; i<xmlNodes.length; i++) 
                newRow = tableNode.insertRow(i);
                newRow.className = (i%2) ? "OddRow" : "EvenRow";
                for (j=0; j<xmlNodes[i].childNodes.length; j++) 
                    newCell = newRow.insertCell(newRow.cells.length);

                    if (xmlNodes[i].childNodes[j].firstChild) 
                        newCell.innerHTML = xmlNodes[i].childNodes[j].firstChild.nodeValue;
                     else 
                        newCell.innerHTML = "-";
                    
                    console.log("cell: " + newCell);

                
                
                theTable.appendChild(tableNode);
        

        function removeWhitespace(xml) 
            var loopIndex;
            for (loopIndex = 0; loopIndex < xml.childNodes.length; loopIndex++)
            
                var currentNode = xml.childNodes[loopIndex];
                if (currentNode.nodeType == 1)
                
                    removeWhitespace(currentNode);
                
                if (!(/\S/.test(currentNode.nodeValue)) && (currentNode.nodeType == 3))
                
                    xml.removeChild(xml.childNodes[loopIndex--]);
                
            
        

但是这段代码会为&lt;business&gt; 元素下的所有节点打印列。并且&lt;business&gt;下的子元素个数不同。所以结果是这样的

我不想要那个。我只想在 &lt;business&gt; 元素下显示特定节点的值(在这种情况下只包括 &lt;advertHeader&gt; ; &lt;Price&gt;&lt;description&gt; ),以便每行中的列数相等。怎么做?

【问题讨论】:

您针对哪些浏览器?当您使用客户端 XSLT 和 HTML 表格时,您想到了什么样的分页? @MartinHonnen 所有常规浏览器,即 Chrome、Safari、Firefox,即。 关于分页我没有什么特别的想法。理想情况下每页列出 10 个 ro 【参考方案1】:

尝试找到具有最多值的&lt;business&gt;-元素并围绕它构建您的表格。这是一个示例 sn-p 对您提供的数据执行此操作。


  const xml = new DOMParser()
    .parseFromString(getData(), `text/xml`);
  
  // the <business>-elements from xml
  const businessElems = [...xml.querySelectorAll(`business`)];
  
  // the nodeNames will be the header. While we're at it,
  // we can count the number of headers (len) for later use
  const headersFromXml = businessElems.map( v => 
    [...v.querySelectorAll(`*`)]
      .map( v => v.nodeName) )
      .map( v => ( len: v.length, headers: v ) 
  );
  
  // now determine the longest header using a reducer
  const businessElemWithMostNodes = headersFromXml
    .reduce( (acc, v) => v.len > acc.len ? v : acc, len: 0);
  
  // utility to create a tablecell/header and append it to a row
  const createCell = (rowToAppendTo, cellType, value) => 
    const cell = document.createElement(cellType);
    cell.innerHTML = value;
    rowToAppendTo.appendChild(cell);
  
  
  // utility to create a datarow and append it to a table
  const createDataRow = (tableToAppendTo, businessElem) => 
    const row = document.createElement(`tr`);
    const rowValues = [];
    
    // create values using the businessElemWithMostNodes order
    businessElemWithMostNodes.headers
      .forEach( head => 
        const valueElem = businessElem.querySelector(`$head`);
        rowValues.push(valueElem ? valueElem.innerHTML : `-`);
      );
    
    rowValues.forEach( v => createCell(row, `td`, v) );
    tableToAppendTo.appendChild(row);
  ;
  
  // now we know enough to create the table
  const table = document.createElement(`table`);
  
  // the headerRow first
  const headRow = document.createElement(`tr`);
  businessElemWithMostNodes.headers.forEach( hv => createCell(headRow, `th`, hv) );
  table.appendChild(headRow);
  
  // next create and append the rows
  businessElems.forEach(be => createDataRow(table, be));
  
  // finally, append the table to document.body
  document.body.appendChild(table);
  
  // your xml string
  function getData() 
    return `
    <businesses>
      <business bfsId="" id="41481">
        <advertHeader>Welding Supplies, Equipment and Service Business</advertHeader>
        <Price>265000</Price>
        <catalogueDescription>Extremely profitable (Sales £500k, GP £182k) business</catalogueDescription>
        <keyfeature1>
          Well established 25 year business with excellent trading record
        </keyfeature1>
        <keyfeature2>
          Consistently high levels of turnover and profitability over last 5 years
        </keyfeature2>
      </business>
      <business bfsId="" id="42701">
        <broker bfsRef="1771" ref="003">Birmingham South, Wolverhampton &amp; West Midlands</broker>
        <tenure>freehold</tenure>
        <advertHeader>Prestigious Serviced Office Business</advertHeader>
        <Price>1200000</Price>
        <reasonForSale>This is a genuine retirement sale.</reasonForSale>
        <turnoverperiod>Annual</turnoverperiod>
        <established>28</established>
        <catalogueDescription>This well-located and long-established serviced office</catalogueDescription>
        <underOffer>No</underOffer>
        <image1>https://www.business-partnership.com/uploads/business/businessimg15977.jpg</image1>
        <keyfeature1>other connections</keyfeature1>
        <keyfeature2> Investment Opportunity</keyfeature2>
        <keyfeature3>Over 6,000 sq.ft.</keyfeature3>
        <keyfeature4>Well-maintained </keyfeature4>
        <keyfeature5>In-house services &amp; IT provided</keyfeature5>
      </business>
    </businesses>`;
  
body 
  margin: 1rem;
  font: 12px/15px normal consolas, verdana, arial;


.hidden 
  display: none;


th 
  background-color: black;
  color: white;
  border: 1px solid transparent;
  padding: 2px;
  text-align: left;


td 
  border: 1px solid #c0c0c0;
  padding: 2px;
  vertical-align: top;

【讨论】:

感谢您的回答。那真的很有帮助。正如您在 xml 代码中看到的,子节点的位置也不相似。对于第一个 节点,第一个子节点是 ,而对于第二个 节点, 节点位于第三位。因此,结果可能会令人困惑。我该如何克服这一点 @Bashabi 这是一个不同的问题;)。在我的回答中,解决了“不完整的行问题”。节点顺序可以通过使用longest 并使用querySelector 中的每个节点名称迭代business-elements 来解决 嗯,保持顺序没那么难,看修改后的代码。 非常感谢。在您的示例中,您将 xml 代码作为字符串传递。有什么办法可以将其作为链接传递。并从该链接获取内容。因为我的 xml 文件太长了 “有什么方法可以作为链接传递吗?”不在这个(***-)上下文中,你必须自己弄清楚,对不起。也许 jsFiddle (docs.jsfiddle.net/external-resources) 可以提供帮助

以上是关于如何使用 Javascript 在 HTML 文件中显示 XML 内容的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 javascript 创建 HTML 文件 [关闭]

如何在 JavaScript 文件中使用 Django 变量?

如何使用 C# 执行 HTML 文件的所有 Javascript 以仅生成 HTML DOM

如何仅使用 HTML 和 Javascript 在本地网页上显示文件夹列表? [关闭]

如何在 html 网站上使用 javascript 读取和写入另一个文件?

如何在 Web 浏览器和 XCode 中使用 JavaScript 运行 HTML 文件?