parser

Написать ответ на текущее сообщение

 

 
   команды управления поиском

JSON

G_Z 04.09 04:30 / 04.09 04:33

Берём XML, пишем к нему XSLT-шаблон по преобразованию в JSON.
Можно преобразовывать сразу в парсерный код и делать process, но это небезопасно.
$xml[<a>
	<b>
		<c>
			<id>111</id>
		</c>
		<c>
			<id>222</id>
			<d>
				<e id="333"/>
				<e id="444"/>
			</d>
		</c>
	</b>
</a>]

$xsl[<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:strip-space elements="*"/>

	<xsl:template match="/">
		<xsl:text>[</xsl:text>
		<xsl:apply-templates/>
		<xsl:text>]</xsl:text>
	</xsl:template>

	<xsl:template match="node()">
		<xsl:text>{</xsl:text>
			<xsl:value-of select="concat('&quot^;name&quot^;: &quot^;', local-name(), '&quot^;')"/>
			<xsl:if test="@*">
				<xsl:text>,</xsl:text>
				<xsl:text>"attributes": {</xsl:text>
				<xsl:apply-templates select="@*"/>
				<xsl:text>}</xsl:text>
			</xsl:if>
			<xsl:if test="node() and not(text())">
				<xsl:text>,</xsl:text>
				<xsl:text>"children": [</xsl:text>
				<xsl:apply-templates/>
				<xsl:text>]</xsl:text>
			</xsl:if>
			<xsl:if test="text()">
				<xsl:text>,</xsl:text>
				<xsl:value-of select="concat('&quot^;text&quot^;: &quot^;', ., '&quot^;')"/>
			</xsl:if>
		<xsl:text>}</xsl:text>
		<xsl:if test="position() != last()">
			<xsl:text>,</xsl:text>
		</xsl:if>
	</xsl:template>

	<xsl:template match="@*">
		<xsl:value-of select="concat('&quot^;', name(), '&quot^;: &quot^;', ., '&quot^;')"/>
		<xsl:if test="position() != last()">
			<xsl:text>,</xsl:text>
		</xsl:if>
	</xsl:template>
</xsl:stylesheet>]

$xml[^xdoc::create{$xml}]
$xsl[^xdoc::create{$xsl}]

$json[^xml.transform[$xsl]]
$json[^taint[as-is;^json.string[$.method[text]]]]
Получаем:
[
	{
		"children": [
			{
				"children": [
					{
						"children": [
							{
								"name": "id",
								"text": "111"
							}
						],
						"name": "c"
					},
					{
						"children": [
							{
								"name": "id",
								"text": "222"
							},
							{
								"children": [
									{
										"attributes": {
											"id": "333"
										},
										"name": "e"
									},
									{
										"attributes": {
											"id": "444"
										},
										"name": "e"
									}
								],
								"name": "d"
							}
						],
						"name": "c"
					}
				],
				"name": "b"
			}
		],
		"name": "a"
	}
]
Разбираем:
$hash[^json:parse[$json]]
Получаем объект в хеше, с которым можно работать:
{
	"0": {
		"name": "a",
		"children": {
			"0": {
				"name": "b",
				"children": {
					"0": {
						"name": "c",
						"children": {
							"0": {
								"name": "id",
								"text": "111"
							}
						}
					},
					"1": {
						"name": "c",
						"children": {
							"0": {
								"name": "id",
								"text": "222"
							},
							"1": {
								"name": "d",
								"children": {
									"0": {
										"name": "e",
										"attributes": {
											"id": "333"
										}
									},
									"1": {
										"name": "e",
										"attributes": {
											"id": "444"
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
}
Но на больших документах с памятью будет беда.
И исходный документ — говно, особенно в части пересечения узлов и атрибутов с одинаковым смыслом.