如何使用xslt解析另一个xml的CDATA中的xml? [英] how to parse the xml inside CDATA of another xml using xslt?

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

问题描述

我需要使用单个 XSLT 在 XML 的 CDATA 中转换 XML.

I need to transform the XML inside the CDATA of the XML using the single XSLT.

我有一个如下的 XML,CDATA 中有 xml,如下面的 xml.

I have an XML as below with xml inside the CDATA as in the below xml.

    <message channel-id="e01db0aa-b3db-4b6c-a055-7a0d5c1d1f20" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
    <send-parameters>
               <agent-parameter multi-valued="false">
                 <name>Networks</name>
                 <value><![CDATA[<Networks>
    <Network>
      <GroupCode>EXTPRI</GroupCode>
      <NetworkTypeId>LANI</NetworkTypeId>   
      <OrgNetworkPlatformName>EON-0cbu0cust12301dcd-D-PCL-0002</OrgNetworkPlatformName>
      <OrgNetworkPlatformID>urn:vcloud:network:b7ccfd5f-cfd7-48eb-9dd6-1989b08d7b86</OrgNetworkPlatformID>
      </Network>
      <Network>
      <GroupCode>EXTPRI</GroupCode>
      <NetworkTypeId>LANI</NetworkTypeId>   
      <OrgNetworkPlatformName>ABC-0cbu0cust12301dcd-D-PCL-XYZ</OrgNetworkPlatformName>
      <OrgNetworkPlatformID>urn:vcloud:network:b7ccfd5f-cfd7-48eb-9dd6-1989b08d7b86</OrgNetworkPlatformID>
    </Network>

    </Networks>]]></value>
               </agent-parameter>

                        </send-parameters>
          </message>

我需要将 xml 转换为:

I need to transform the xml into :

    <?xml version="1.0" encoding="UTF-8"?>
    <message xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" channel-id="7652d759-4b32-44d4-8a27-9e390f0cae7b">
        <send-parameters>
            <agent-parameter multi-valued="false">
                <name>ExternalPublicOrgNWPlatformID_DDC</name>
                <value>EON-0cbu0cust12301dcd-D-PCL-0002</value>
            </agent-parameter>
                    <agent-parameter multi-valued="false">
                <name>ExternalPublicOrgNWPlatformID_DS</name>
                <value>ABC-0cbu0cust12301dcd-D-PCL-XYZ</value>
            </agent-parameter>
        </send-parameters>
    </message>

这是我给出的示例输出,我需要遍历 xml 中的多个节点并生成输出 xml.

This is the sample output I have given there would be multiple nodes inside the xml that i need to traverse through and generate the output xml.

我通过将 xpath 指向源 xml 的 cdata 内的节点来使用 xslt.但它是空的,因为它不是树结构格式.

I am using the xslt by directing the xpath upto the node inside the cdata of the source xml. but it is giving empty as it was not in a tree structure format.

我无法在 CDATA 中获取 xml 的 X 路径.如果我删除 xml 中的 CDATA ,它运行良好,但 xml 来自无法修改的外部系统.

I can not get the X-Path for the xml inside the CDATA. It is working well if I remove CDATA in the xml , but the xml is comming from the external system which can not be modified.

我不能使用多个 xslt,我需要应用单个 XSLT.

I can't use multiple xslts I need to apply single XSLT.

你能不能给我建议一下.

Could you please suggest me on this.

非常感谢期待..

推荐答案

此 XSLT 生成所需的输出:

This XSLT produces the output required:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
xmlns:exsl="http://exslt.org/common" 
extension-element-prefixes="exsl">
<xsl:output indent="yes"/>
<xsl:template match="/">
    <xsl:variable name="cdata"
        select="message/send-parameters/agent-parameter/value"/>
    <xsl:variable name="parsedXml_">
        <xsl:call-template name="parseXml">
            <xsl:with-param name="text" select="$cdata"/>
        </xsl:call-template>
    </xsl:variable>
    <xsl:variable name="parsedXml" select="exsl:node-set($parsedXml_)"/>
    <message xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >
        <xsl:attribute name="channel">
            <xsl:value-of select="message/@channel-id"/>
        </xsl:attribute>
        <send-parameters>
            <agent-parameter multi-valued="false">
                <name>ExternalPublicOrgNWPlatformID_DDC</name>
                <value>
                    <xsl:value-of select="$parsedXml/Networks/Network[1]/OrgNetworkPlatformName"/>
                </value>
            </agent-parameter>
            <agent-parameter multi-valued="false">
                <name>ExternalPublicOrgNWPlatformID_DS</name>
                <value>
                    <xsl:value-of select="$parsedXml/Networks/Network[2]/OrgNetworkPlatformName"/>
                </value>
            </agent-parameter>
        </send-parameters>
    </message>
</xsl:template>
<xsl:template name="parseXml">
    <xsl:param name="text"/>
    <xsl:choose>
        <xsl:when test="contains($text, '&gt;')">
            <xsl:variable name="topLevelTag">
                <xsl:call-template name="getTopLevelTag">
                    <xsl:with-param name="text" select="$text"/>
                </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="openingTag">
                <xsl:value-of select="$topLevelTag"/>
            </xsl:variable>
            <xsl:variable name="tagName">
                <xsl:call-template name="getTopLevelTagName">
                    <xsl:with-param name="text" select="$text"/>
                </xsl:call-template>
            </xsl:variable>
            <xsl:variable name="closingTag">
                <xsl:value-of select="concat('&lt;/',$tagName,'&gt;')"/>
            </xsl:variable>
            <xsl:variable name="firstNode">
                <xsl:if test="not(contains($topLevelTag,'/&gt;'))">
                    <xsl:value-of select="substring-before(substring-after($text,$openingTag),$closingTag)"/>        
                </xsl:if>
            </xsl:variable>
            <xsl:variable name="afterFirstNode">
                <xsl:choose>
                    <xsl:when test="not(contains($topLevelTag,'/&gt;'))">
                        <xsl:value-of select="substring-after($text,concat($firstNode,$closingTag))"/>        
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="substring-after($text,$topLevelTag)"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:element name="{$tagName}">
                <xsl:call-template name="createAttributes">
                    <xsl:with-param name="text" select="$topLevelTag"/>
                </xsl:call-template>
                <xsl:call-template name="parseXml">
                    <xsl:with-param name="text" select="$firstNode"/>
                </xsl:call-template>
            </xsl:element>
            <xsl:call-template name="parseXml">
                <xsl:with-param name="text" select="$afterFirstNode"/>
            </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="$text"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
<xsl:template name="getTopLevelTagName">
    <xsl:param name="text"/>
    <xsl:choose>
        <xsl:when test="contains($text, '&gt;')">
            <xsl:variable name="tagWithAttributesWithoutEnd">
                <xsl:value-of select="substring-before($text, '&gt;')"/>
            </xsl:variable>
            <xsl:variable name="tagWithAttributesWithoutBegining">
                <xsl:value-of select="substring-after($tagWithAttributesWithoutEnd, '&lt;')"/>
            </xsl:variable>
            <xsl:variable name="tagName">
                <xsl:choose>
                    <xsl:when test="contains($tagWithAttributesWithoutBegining,' ')">
                        <xsl:value-of
                            select="substring-before($tagWithAttributesWithoutBegining, ' ')"/>
                    </xsl:when>
                    <xsl:otherwise>
                        <xsl:value-of select="$tagWithAttributesWithoutBegining"/>
                    </xsl:otherwise>
                </xsl:choose>
            </xsl:variable>
            <xsl:value-of select="$tagName"/>
        </xsl:when>
    </xsl:choose>
</xsl:template>
<xsl:template name="getTopLevelTag">
    <xsl:param name="text"/>
    <xsl:choose>
        <xsl:when test="contains($text, '&gt;')">
            <xsl:variable name="tagWithAttributesWithoutEnd">
                <xsl:value-of select="substring-before($text, '&gt;')"/>
            </xsl:variable>
            <xsl:value-of select="concat($tagWithAttributesWithoutEnd,'&gt;')"/>
        </xsl:when>
    </xsl:choose>
</xsl:template>
<xsl:template name="createAttributes">
    <xsl:param name="text"/>
    <xsl:choose>
        <xsl:when test="contains($text, '=&quot;')">
            <xsl:variable name="attributeName">
                <xsl:value-of select="substring-before(substring-after($text,' '),'=&quot;')"/>
            </xsl:variable>
            <xsl:message>
                <xsl:value-of select="$text"/>
            </xsl:message>
            <xsl:variable name="attributeValue">
                <xsl:value-of select="substring-before(substring-after($text,concat($attributeName,'=&quot;')),'&quot;')"/>
            </xsl:variable>
            <xsl:attribute name="{$attributeName}">
                <xsl:value-of select="$attributeValue"/>
            </xsl:attribute>
            <xsl:call-template name="createAttributes">
                <xsl:with-param name="text" select="substring-after($text,concat($attributeName,'=&quot;',$attributeValue,'&quot;'))"/>
            </xsl:call-template>
        </xsl:when>
    </xsl:choose>        
</xsl:template>
</xsl:stylesheet>

这篇关于如何使用xslt解析另一个xml的CDATA中的xml?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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