简体   繁体   English

GET 请求 XML 响应解析使用 XPath 生成 JS Object

[英]GET Request XML response parsing using XPath to produce a JS Object

The problem is that I get an "application/xml" response from a GET request to a WMS server which I then use the DOMParser().parseFromString() method to parse using an XPath expression.问题是我从 GET 请求到 WMS 服务器获得了“应用程序/xml”响应,然后我使用 DOMParser().parseFromString() 方法使用 XPath 表达式进行解析。 I tried looking at different solutions like dedicated libraries but I found out about XPath expressions and now I need help writing a XPath expression that will return me the Layer tags' names and titles of an XML response that looks like我尝试查看不同的解决方案,如专用库,但我发现了 XPath 表达式,现在我需要帮助编写一个 XPath 表达式,它将返回层标签的名称和标题 Z3501BB093D363810B671059B9CFEDF88 响应看起来像

<Layer>
<Title>Title Level 1</Title>
<Name>Name Level 1</Name>
    <Layer>
    <Title>Title Level 2</Title>
    <Name>Name Level 2</Name>
        <Layer>
        <Title>Title Level 3-1</Title>
        <Name>Name Level 3-1</Name>
        </Layer>
        <Layer>
        <Title>Title Level 3-2</Title>
        <Name>Name Level 3-2</Name>
        </Layer>
    </Layer>
</Layer>

And would return me a JSON并且会给我一个 JSON

{
title: 'Title Level 1'
name: 'Name Level 1'
children: [
    {
     title: 'Title Level 2'
     name: 'Name Level 2'
     children: [
         {
          title: 'Title Level 3-1'
          name: 'Name Level 3-1'
         },
         {
          title: 'Title Level 3-1'
          name: 'Name Level 3-1'
         }
     ]
]
}

You can use XSLT 3 with Saxon-JS 2 ( https://www.saxonica.com/download/javascript.xml ) in the browser to transform XML to JSON: You can use XSLT 3 with Saxon-JS 2 ( https://www.saxonica.com/download/javascript.xml ) in the browser to transform XML to JSON:

 const xml = `<Layer> <Title>Title Level 1</Title> <Name>Name Level 1</Name> <Layer> <Title>Title Level 2</Title> <Name>Name Level 2</Name> <Layer> <Title>Title Level 3-1</Title> <Name>Name Level 3-1</Name> </Layer> <Layer> <Title>Title Level 3-2</Title> <Name>Name Level 3-2</Name> </Layer> </Layer> </Layer>`; const xslt = `<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all" xmlns="http://www.w3.org/2005/xpath-functions" expand-text="yes" version="3.0"> <xsl:output method="json" build-tree="no"/> <xsl:template match="/*" priority="5"> <xsl:variable name="json-xml"> <map> <xsl:apply-templates/> </map> </xsl:variable> <xsl:sequence select="xml-to-json($json-xml) => parse-json()"/> </xsl:template> <xsl:template match="*[not(*)]"> <string key="{local-name()}">{.}</string> </xsl:template> <xsl:template match="Layer[1]"> <array key="children"> <xsl:apply-templates select="../Layer" mode="map"/> </array> </xsl:template> <xsl:template match="Layer[position() > 1]"/> <xsl:template match="Layer" mode="map"> <map> <xsl:apply-templates/> </map> </xsl:template> </xsl:stylesheet>`; const jsonResult = SaxonJS.XPath.evaluate(`transform(map { 'source-node': parse-xml($xml), 'stylesheet-text': $xslt, 'delivery-format': 'raw' })?output`, [], { 'params': { 'xml': xml, 'xslt': xslt } }); console.log(jsonResult);
 <script src="https://xsltfiddle-beta.liberty-development.net/js/SaxonJS2/SaxonJS2.js"></script>

A slightly different but perhaps more compact XSLT 3 approach would be to directly transform the XML to maps and arrays output as JSON objects and arrays: A slightly different but perhaps more compact XSLT 3 approach would be to directly transform the XML to maps and arrays output as JSON objects and arrays:

 const xml = `<Layer> <Title>Title Level 1</Title> <Name>Name Level 1</Name> <Layer> <Title>Title Level 2</Title> <Name>Name Level 2</Name> <Layer> <Title>Title Level 3-1</Title> <Name>Name Level 3-1</Name> </Layer> <Layer> <Title>Title Level 3-2</Title> <Name>Name Level 3-2</Name> </Layer> </Layer> </Layer>`; const xslt = `<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="#all" xmlns="http://www.w3.org/2005/xpath-functions" xmlns:mf="http://example.com/mf" expand-text="yes" version="3.0"> <xsl:strip-space elements="*"/> <xsl:output method="json" build-tree="no" indent="yes"/> <xsl:template match="/Layer" priority="5"> <xsl:map> <xsl:apply-templates/> </xsl:map> </xsl:template> <xsl:template match="*[not(*)]"> <xsl:map-entry key="local-name()" select="data()"/> </xsl:template> <xsl:template match="Layer[1]"> <xsl:map-entry key="'children'"> <xsl:sequence select="array {../Layer/mf:apply-templates(.) }"/> </xsl:map-entry> </xsl:template> <xsl:template match="Layer[position() > 1]"/> <xsl:function name="mf:apply-templates" as="item()*"> <xsl:param name="elements" as="element(*)*"/> <xsl:map> <xsl:apply-templates select="$elements/*"/> </xsl:map> </xsl:function> </xsl:stylesheet>`; const jsonResult = SaxonJS.XPath.evaluate(` transform( map { 'source-node': parse-xml($xml), 'stylesheet-text': $xslt, 'delivery-format': 'raw' } )?output`, [], { 'params': { 'xml': xml, 'xslt': xslt } } ); console.log(jsonResult);
 <script src="https://xsltfiddle-beta.liberty-development.net/js/SaxonJS2/SaxonJS2.js"></script>

In both examples for compactness (and elegance of a executable single StackOverflow code snippet) I used XPath 3.1 transform function to run XSLT 3 code directly from JavaScript; In both examples for compactness (and elegance of a executable single StackOverflow code snippet) I used XPath 3.1 transform function to run XSLT 3 code directly from JavaScript; while Saxon-JS 2 supports that flawlessly both in the browser and in Node.js it should be noted that, for performance reasons, the recommended way, if you have the XSLT developed and fixed, is to pre-compile with Saxon EE or with Saxon JS 2's xslt3 command line from XSLT to SEF (ie from the XML based XSLT code to the JSON based SEF format) so that the SEF can be fed directly to the transform function in the Saxon JS API https://www.saxonica.com/saxon-js/documentation/index.html#!api/transform .虽然 Saxon-JS 2 在浏览器和 Node.js 中都完美支持,但应该注意,出于性能原因,如果您开发和修复了 XSLT,推荐的方法是使用 Saxon EE 或 Saxon JS 进行预编译2's xslt3 command line from XSLT to SEF (ie from the XML based XSLT code to the JSON based SEF format) so that the SEF can be fed directly to the transform function in the Saxon JS API https://www.saxonica.com/ saxon-js/documentation/index.html#!api/transform That should perform much better in real world scenarios than using SaxonJS.XPath.evaluate and on Node.js additionally allows you to use async programming.这在现实世界的场景中应该比使用SaxonJS.XPath.evaluate和在 Node.js 上执行得更好,还允许您使用异步编程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM