如何使用xpath编辑特定的xml

VSS

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

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>

X路径

/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>

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

马丁·洪恩

给定XSLT 3的一种方法可能是将您拥有的路径转换为XSLT 3匹配模板,然后创建可以使用该transform函数执行的样式表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>

这样,虽然我不得不去适应的路径,包括bikesbikes[1]

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何编辑XML DOMDocument的特定节点值?

如何使用XPath和Java更新XML

如何使用XPATH到达特定的子节点?

如何使用Java中的XPath从XML提取特定节点?

如何使用HXT编辑XML文件中的特定元素?

在SSIS中,如何使用Foreach NodeList枚举器中的XPATH在特定元素内循环遍历XML

如何对特定文本使用XPath contains()?

如何在Python中使用XPath限制特定xml元素的开始和结束标记之间的元素提取范围?

如何使用PHP编辑特定的JSON键值

使用XPath从XML文档中提取标记特定的数据

如何通过该特定XML对邮件进行xPath?

如何使用xpath(php)查询xml文件?

使用XPath或XSLT从XML中排除特定元素

如何使用python编辑特定目录中XML文件的多个xml标记数据

如何使用xpath查找特定类型的所有xml元素?

如何使用XPath查找特定元素?

xpath:如何使用xpath获取特定的文本?

如何对给定的XML使用Xpath

如何使用Xpath从XML文件获取特定值

如何使用xpath或查询从xml提取数据

如何使用imacros xpath提取特定文本

如何使用XPath根据条件获取XML containsg默认名称空间中的特定元素

如何使用python编辑文件的特定列

如何使用 XPath 1.0 选择特定 XML 注释前面的元素?

如何通过 XPath 按 XML 中的特定值进行过滤

如何在带有 xmlns 属性的 xml 中使用 xpath 获取特定的嵌套元素?

使用 C# 批量编辑 XML 中的特定元素

如何使用 Angular8 编辑特定行内联编辑

如何使用python编辑xml根属性