如何使用xpath编辑特定的xml [英] How to edit specific xml using xpath

查看:132
本文介绍了如何使用xpath编辑特定的xml的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下xml,它是使用xslt函数json-to-xml()生成的。我需要使用给定的xpath更新此xml,如结果xml中所示。我需要java或xslt中的解决方案。任何帮助将非常感激。

I have got below xml which is genrated using xslt function json-to-xml(). I need to update this xml as shown in Result xml using given xpaths. I need the solution in java or xslt. Any help would be much appreciated.

XML

 <?xml version="1.0" encoding="UTF-8"?>
    <map xmlns="http://www.w3.org/2005/xpath-functions">
        <map key="Response">
            <map key="Headers">
                <string key="server">Lisa</string>
                <string key="Status-Code">200</string>
                <string key="Content-Type">applicaton/json</string>
            </map>
            <map key="Payload">
                <map key="root">
                    <array key="cars">
                        <map>
                            <string key="company">ccc</string>
                            <string key="model">mmm</string>
                        </map>
                        <map>
                            <string key="strength">666</string>
                            <string key="Capacity">333</string>
                        </map>
                    </array>
                    <array key="bikes">
                        <map>
                            <string key="company">abc</string>
                            <string key="model">2018</string>
                        </map>
                    </array>
                </map>
            </map>
        </map>
    </map>

XPATHS

/Response/Payload/root/cars[2]/strength=999
/Response/Payload/root/bikes/model=2019
/Response/Headers/server=WebSphere
/Response/Headers/Content-Type=text
/Response/Payload/root/cars[2]/Capacity=555
/Response/Payload/root/cars[1]/model=mmm1
/Response/Payload/root/bikes/company=xyz
/Response/Payload/root/cars[1]/company=ccc1
/Response/Headers/Status-Code=400

更新后的结果XML

<map xmlns="http://www.w3.org/2005/xpath-functions">
    <map key="Response">
        <map key="Headers">
            <string key="server">WebSphere</string>
            <string key="Status-Code">400</string>
            <string key="Content-Type">text</string>
        </map>
        <map key="Payload">
            <map key="root">
                <array key="cars">
                    <map>
                        <string key="company">ccc1</string>
                        <string key="model">mmm1</string>
                    </map>
                    <map>
                        <string key="strength">999</string>
                        <string key="Capacity">555</string>
                    </map>
                </array>
                <array key="bikes">
                    <map>
                        <string key="company">xyz</string>
                        <string key="model">2019</string>
                    </map>
                </array>
            </map>
        </map>
    </map>
</map>

我的尝试

我试过转换这个xml使用xslt函数返回json,然后使用com.jayway.jsonpath Jayway JsonPath 库进行解析/更改给定xpath上的json值。然后最后使用xslt函数将json再次更改为xml。这对我来说就像魅力一样!
但是在使用这个库之后我开始在我的应用程序的其他部分遇到问题:(。所有json请求体的发布请求都开始给出400错误。错误是错误400客户端发送的请求在语法上不正确。我无法弄清楚问题,可能是由于不同的jar骗局。
所以我正在尝试其他方式工作。任何其他库如Jayway JsonPath?或任何其他解决方案/建议将有助于alot。

My Try
I have tried converting this xml back to json using xslt function and then used com.jayway.jsonpath Jayway JsonPath library to parse/change values of json on given xpaths. And then finally changed that json again to xml using xslt function. This worked for me like charm !! But after using this library i started facing issues in my other part of application :( . All the post request with json request body started giving 400 error. The error was "Error 400 The request sent by the client was syntactically incorrect" . I couldn't figure out the issue and may be it was due to different jar conficts. So I am trying some other way to work. Any other library like Jayway JsonPath? Or any other solution/Suggestion will help alot.

推荐答案

给定XSLT 3的一种方法可能是将您拥有的路径转换为XSLT 3匹配模板,然后创建样式表您可以使用转换函数执行( https://www.w3.org/TR/xpath-functions/#func-transform ):

One approach given XSLT 3 might be to transform those paths you have into XSLT 3 match templates and then create a stylesheet you can execute with the transform function (https://www.w3.org/TR/xpath-functions/#func-transform):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:axsl="http://www.w3.org/1999/XSL/Transform-alias"
    exclude-result-prefixes="xs"
    version="3.0">

    <xsl:namespace-alias stylesheet-prefix="axsl" result-prefix="xsl"/>

    <xsl:output method="xml" indent="yes"/>

    <xsl:param name="paths" as="xs:string">/Response/Payload/root/cars[2]/strength=999
        /Response/Payload/root/bikes[1]/model=2019
        /Response/Headers/server=WebSphere
        /Response/Headers/Content-Type=text
        /Response/Payload/root/cars[2]/Capacity=555
        /Response/Payload/root/cars[1]/model=mmm1
        /Response/Payload/root/bikes[1]/company=xyz
        /Response/Payload/root/cars[1]/company=ccc1
        /Response/Headers/Status-Code=400</xsl:param>

    <xsl:param name="path-sequence" as="xs:string*" select="tokenize($paths, '\s+')!normalize-space()"/>

    <xsl:variable name="stylesheet">
        <axsl:stylesheet version="3.0">
            <axsl:mode on-no-match="shallow-copy"/>

            <xsl:for-each select="($path-sequence)">
                <xsl:variable name="steps" select="tokenize(., '/')"/>
                <axsl:template>
                    <xsl:attribute name="match">
                        <xsl:apply-templates select="tail($steps)" mode="step"/>
                    </xsl:attribute>
                    <axsl:copy>
                        <axsl:copy-of select="@*"/>
                        <xsl:value-of select="substring-after($steps[last()], '=')"/>
                    </axsl:copy>                   
                </axsl:template>
            </xsl:for-each>

        </axsl:stylesheet>
    </xsl:variable>

    <xsl:template match=".[not(contains(., '[')) and not(contains(., '='))]" mode="step">
        <xsl:if test="position() gt 1">/</xsl:if>
        <xsl:sequence select="'*[@key = ''' || . || ''']'"/>
    </xsl:template>

    <xsl:template match=".[contains(., '=')]" mode="step">
        <xsl:if test="position() gt 1">/</xsl:if>
        <xsl:sequence select="'*[@key = ''' || substring-before(., '=') || ''']'"/>
    </xsl:template>

    <xsl:template match=".[contains(., '[')]" mode="step">
        <xsl:if test="position() gt 1">/</xsl:if>
        <xsl:sequence select="'*[@key = ''' || substring-before(., '[') || ''']/*[' || replace(., '^[^\[]+\[([0-9]+)\]', '$1') || ']'"/>
    </xsl:template>

    <xsl:template match="/">
        <xsl:sequence select="transform(map {
            'source-node' : .,
            'stylesheet-node' : $stylesheet
          })?output"/>
    </xsl:template>

</xsl:stylesheet> 

https://xsltfiddle.liberty-development.net/jyyiVhv/1 我得到想要的结果

<?xml version="1.0" encoding="UTF-8"?>
<map xmlns="http://www.w3.org/2005/xpath-functions">
    <map key="Response">
        <map key="Headers">
            <string key="server">WebSphere</string>
            <string key="Status-Code">400</string>
            <string key="Content-Type">text</string>
        </map>
        <map key="Payload">
            <map key="root">
                <array key="cars">
                    <map>
                        <string key="company">ccc1</string>
                        <string key="model">mmm1</string>
                    </map>
                    <map>
                        <string key="strength">999</string>
                        <string key="Capacity">555</string>
                    </map>
                </array>
                <array key="bikes">
                    <map>
                        <string key="company">xyz</string>
                        <string key="model">2019</string>
                    </map>
                </array>
            </map>
        </map>
    </map>
</map>

虽然我不得不调整路径,包括 bikes 自行车[1]

that way although I had to adapt the paths including bikes to bikes[1].

这篇关于如何使用xpath编辑特定的xml的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆