XHR,XPath和自定义本地XML架构

时间:2015-06-14 20:22:28

标签: javascript xml html5 xpath xmlhttprequest

虽然在(X)HTML5(例如SVG)中使用XML扩展是可能的,并且有些常见,解析XHTML5文档,使用自定义本地XSD扩展,但使用XPath会导致意外结果。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns:hp="http://homepage.org/homepage" 
      hp:schemaLocation="http://homepage.org ./schemas/homepage.xsd">
  <head>
    ...
  </head>
  <body>
    <hp:homepage title="Homepage">
    <header>
      <h1></h1>
    </header>
    ...

利用通常的NSResolver逻辑会导致命名空间错误:

  var hpResolver = document.createNSResolver( document.ownerDocument == null ? document.documentElement : document.ownerDocument.documentElement);

创建自定义处理程序不会导致错误,但XPath仍然无法返回预期结果:

  var hpResolver = function (prefix) {
    if (prefix === 'hp') {
      return 'http://homepage.org/homepage';
    } else {
      return null;
    }
  };

XSD正在提供其余文件,并且正在本地文件系统而不是服务器上进行测试,作为教育练习。

XPath查询如下:

  var path = '/html/body/hp:homepage/header/h1';
  var headTitle = document.evaluate(path, document, hpResolver, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;

以上样本仅作为示例编写。

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://homepage.org/homepage"
           xmlns="http://homepage.org/homepage"
           elementFormDefault="qualified">

  <xs:element name="homepage">
    <xs:complexType>
      <xs:sequence>
        <xs:attribute name="title" type="xs:string" use="required" />
      </xs:sequence>
    </xs:complexType>
  </xs:element>

</xs:schema>

1 个答案:

答案 0 :(得分:0)

我并不认为模式很重要,因为浏览器没有验证具有模式支持的解析器。重要的是命名空间,如果您想使用自定义元素和命名空间,那么您需要确保正确使用XHTML5,确保您的元素位于命名空间中,确保您将文档提供为application/xhtml+xml(仅限于此它们由理解命名空间的浏览器XML解析器解析,text/html解析器由不支持命名空间的HTML5解析器解析。)

基于此,我创建了具有代码

的示例http://home.arcor.de/martin.honnen/html/test2015061502.xhtml
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>XMLHttpRequest and DOM Level 3 XPath API test with 'application/xhtml+xml' document</title>
<script type="text/javascript"><![CDATA[
function test() {
  var req = new XMLHttpRequest();
  req.open('GET', 'test2015061501.xhtml', true);
  req.onload = function() {
    var doc = req.responseXML;
    var res = function(prefix) {
      if (prefix === 'xhtml') {
        return 'http://www.w3.org/1999/xhtml';
      }
      else if (prefix === 'hp') {
        return 'http://example.com/hp';
      }
      else {
        return null;
      }
    }
    var path = '/xhtml:html/xhtml:body/hp:homepage/xhtml:header/xhtml:h1';
    var val = doc.evaluate(path, doc, res, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
    document.body.insertAdjacentHTML('beforeEnd', '<p>Found ' + val + '</p>');
  };
  req.send();
}

window.onload = test;
]]></script>
</head>
<body>
<h1>XMLHttpRequest and DOM Level 3 XPath API test with 'application/xhtml+xml' document</h1>
</body>
</html>

并加载http://home.arcor.de/martin.honnen/html/test2015061501.xhtml,其中包含XHTML命名空间中的元素和自定义命名空间中的元素:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:hp="http://example.com/hp" 
      hp:schemaLocation="http://example.com/hp ./schemas/homepage.xsd">
  <head>
    ...
  </head>
  <body>
    <hp:homepage title="Homepage">
      <header>
        <h1>I am a heading</h1>
      </header>
    </hp:homepage>
  </body>
</html>

第一个文档中的XPath 1.0表达式为/xhtml:html/xhtml:body/hp:homepage/xhtml:header/xhtml:h1,并找到XHTML h1 HTMLHeadingElement元素,包括Firefox 38和Chrome 43。