xPath XSLT 获取父元素及其子元素和孙元素

酒吧杰克

我需要帮助来改变这样的 xml 结构

<AcctInqRq>
 <MsgRqHdr>
    <RqUID>86eb9644-decf-4fa2-bd16-6d5403a8660a</RqUID>
    <ChannelId>897</ChannelId>
 </MsgRqHdr>
 <InqInfo>
    <FromAccount>
       <AccountId>11012442</AccountId>
       <AccountCurrency/>
    </FromAccount>
 </InqInfo>
 <RefInfo>
    <RefName>AppCallerName</RefName>
    <RefValue>API_GATEWAY</RefValue>
 </RefInfo>
</AcctInqRq>

对此

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:typ="http://www.some.com/esb/inquiry/acct/types" xmlns:core="http://www.some.com/esb/shared/core">
   <soapenv:Header/>
   <soapenv:Body>
      <typ:AcctInqRq>
         <core:MsgRqHdr>
            <core:RqUID>86eb9644-decf-4fa2-bd16-6d5403a8660a</core:RqUID>
            <core:ChannelId>897</core:ChannelId>
         </core:MsgRqHdr>
         <typ:InqInfo>
            <typ:FromAccount>
               <typ:AccountId>11012442</typ:AccountId>
               <typ:AccountCurrency/>
            </typ:FromAccount>
         </typ:InqInfo>
         <core:RefInfo>
            <core:RefName>AppCallerName</core:RefName>
            <core:RefValue>API_GATEWAY</core:RefValue>
         </core:RefInfo>
      </typ:AcctInqRq>
   </soapenv:Body>
</soapenv:Envelope>

这是我目前的 xslt

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:typ="http://www.some.com/esb/inquiry/acct/types" 
xmlns:core="http://www.some.com/esb/shared/core" 
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" encoding="utf-8"/>
    <xsl:template match="/">
        <soapenv:Envelope>
            <soapenv:Header/>
            <soapenv:Body>
                <xsl:apply-templates/>
            </soapenv:Body>
        </soapenv:Envelope>
    </xsl:template>
    <xsl:template match="AcctInqRq|InqInfo|FromAccount|AccountId|AccountCurrency|ToAccount|AccountId|AccountCurrency|ChequeNo|RetrievalNo|SlipNo">
        <xsl:element name="typ:{local-name()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>
    <xsl:template match="MsgRqHdr">
        <xsl:for-each select="*"> 
            <xsl:element name="core:{local-name()}">
                <xsl:apply-templates select="@*|node()"/>
            </xsl:element>
        </xsl:for-each>
    </xsl:template>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

正如您在我尝试手动列出每个元素标签之前的第二个模板标签中看到的那样,但它很耗时。所以现在我想检查父元素,并递归更改所有子元素,并分别添加前缀。你可以看到我在第三个模板标签中尝试过。但它失败了。那我该怎么做呢?另请注意,我们可以覆盖某些字段以不遵守上述规则。例如,根节点是 AccInqRq,应该添加前缀 typ,但它的后代如 MsgRqHdr 和 RefInfo 应该添加前缀核心。

所以我大概是这样想的(CMIIW)

..upper xsl code..
<xsl:template match="MsgRqHdr | RefInfo | *other parent element to be added prefix core*
</xsl:template>

<xsl:template match="InqInfo| *other parent element to be added prefix typ*
</xsl:template>

<xsl:template match=" *probably add this one to override some field with specific prefix typ*
</xsl:template>

谢谢

编辑:还有另一个信息。应该具有前缀core的父级递归的所有子节点,其前缀中不可能有typ虽然父元素的每个子节点都有 typ 前缀,但它的子节点有可能有核心前缀。所以也许我们可以默认为根元素的子元素添加前缀typ,然后我们可以指定哪些子元素应该具有核心前缀

马丁·霍南

您可以为其他元素编写模板并确保设置优先级:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:typ="http://www.some.com/esb/inquiry/acct/types" 
    xmlns:core="http://www.some.com/esb/shared/core" 
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="/">
        <soapenv:Envelope>
            <soapenv:Header/>
            <soapenv:Body>
                <xsl:apply-templates/>
            </soapenv:Body>
        </soapenv:Envelope>
    </xsl:template>

    <xsl:template match="AcctInqRq | AcctInqRq//*">
        <xsl:element name="typ:{local-name()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="MsgRqHdr | MsgRqHdr//* | RefInfo | RefInfo//*" priority="5">
        <xsl:element name="core:{local-name()}">
                <xsl:apply-templates select="@*|node()"/>
            </xsl:element>
    </xsl:template>

</xsl:stylesheet>

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

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

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章