1

我有一个 XML,我需要对其应用 XSL 以将其转换为具有不同架构版本的另一个 XML。架构的两个版本是 V1 和 V2。在我的架构版本 V1 中,ID 允许的最大实例数为 2,但在架构的版本 2 中,它已更改为 3。现在我将版本 2 中的 XML 降级为版本 1 中的 XML,所以我只想保留 2我最终的 XML 中的 ID 类型的实例。如果有人可以让我知道我们如何在 XSLT 中做到这一点,将不胜感激。

输入 XML

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
     <soapenv:Body>
      <tns:send xmlns:tns="http://www.test.com/Service/v3">
         <NS2:Message release="006" version="010" xmlns:NS2="http://www.ncpdp.org/schema/SCRIPT">

            <NS2:Body>
               <NS2:New>
                  <NS2:Pharmacy>
                     <NS2:Identification>
                        <NS2:ID>
                           <NS2:IDValue>01017</NS2:IDValue>
                           <NS2:IDQualifier>94</NS2:IDQualifier>
                           <NS2:IDRegion>SCA</NS2:IDRegion>
                            <NS2:IDState>CA</NS2:IDState>
                        </NS2:ID>
                        <NS2:ID>
                           <NS2:IDValue>01018</NS2:IDValue>
                           <NS2:IDQualifier>95</NS2:IDQualifier>
                           <NS2:IDRegion>SCA</NS2:IDRegion>
                            <NS2:IDState>CA</NS2:IDState>
                        </NS2:ID>
                        <NS2:ID>
                           <NS2:IDValue>01019</NS2:IDValue>
                           <NS2:IDQualifier>96</NS2:IDQualifier>
                           <NS2:IDRegion>SCA</NS2:IDRegion>
                            <NS2:IDState>CA</NS2:IDState>
                        </NS2:ID>
                             </NS2:Identification>
                             </NS2:Pharmacy>
                    </NS2:New>
            </NS2:Body>
         </NS2:Message>
      </tns:send>
   </soapenv:Body>
</soapenv:Envelope>

XSLT:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:tns="http://www.test.com/Service/v3"
    xmlns:NS2="http://www.ncpdp.org/schema/SCRIPT"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

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

    <xsl:template match="tns:*">
        <xsl:element name="{name()}" namespace="http://www.test.com/Service/v1">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>  
    </xsl:template>

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

</xsl:stylesheet>

期望的输出:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <tns:send xmlns:tns="http://www.test.com/Service/v1">
         <NS2:Message xmlns:NS2="http://www.ncpdp.org/schema/SCRIPT" release="006" version="010">
            <NS2:Body>
               <NS2:New>
                  <NS2:Pharmacy>
                     <NS2:Identification>
                        <NS2:ID>
                           <NS2:IDValue>01017</NS2:IDValue>
                           <NS2:IDQualifier>94</NS2:IDQualifier>
                           <NS2:IDRegion>SCA</NS2:IDRegion>
                           <NS2:IDState>CA</NS2:IDState>
                        </NS2:ID>
                        <NS2:ID>
                           <NS2:IDValue>01018</NS2:IDValue>
                           <NS2:IDQualifier>95</NS2:IDQualifier>
                           <NS2:IDRegion>SCA</NS2:IDRegion>
                            <NS2:IDState>CA</NS2:IDState>
                        </NS2:ID>
                            </NS2:Identification>
                             </NS2:Pharmacy>
                    </NS2:New>
                     </NS2:Identification>
                  </NS2:Pharmacy>
               </NS2:New>
            </NS2:Body>
         </NS2:Message>
      </tns:send>
   </soapenv:Body>
</soapenv:Envelope>

应用 XSLT 后我期望的第二个变体是修剪字符串。ID 实例的 IDRegion 为 3 个字符,我想在应用 XSLT 后将其修剪为 2 个字符“SC”。

所以输出类似

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
       <soapenv:Body>
          <tns:send xmlns:tns="http://www.test.com/Service/v1">
             <NS2:Message xmlns:NS2="http://www.ncpdp.org/schema/SCRIPT" release="006" version="010">
                <NS2:Body>
                   <NS2:New>
                      <NS2:Pharmacy>
                         <NS2:Identification>
                            <NS2:ID>
                               <NS2:IDValue>01017</NS2:IDValue>
                               <NS2:IDQualifier>94</NS2:IDQualifier>
                               <NS2:IDRegion>SC</NS2:IDRegion>
                               <NS2:IDState>CA</NS2:IDState>
                            </NS2:ID>
                            <NS2:ID>
                               <NS2:IDValue>01018</NS2:IDValue>
                               <NS2:IDQualifier>95</NS2:IDQualifier>
                               <NS2:IDRegion>SC</NS2:IDRegion>
                                <NS2:IDState>CA</NS2:IDState>
                            </NS2:ID>
                                </NS2:Identification>
                                 </NS2:Pharmacy>
                        </NS2:New>
                         </NS2:Identification>
                      </NS2:Pharmacy>
                   </NS2:New>
                </NS2:Body>
             </NS2:Message>
          </tns:send>
       </soapenv:Body>
    </soapenv:Envelope>
4

1 回答 1

1

这种转换(XSLT 1.0 和 XSLT 2.0):

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
 xmlns:NS2="http://www.ncpdp.org/schema/SCRIPT">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
     <xsl:copy>
       <xsl:apply-templates select="node()|@*"/>
     </xsl:copy>
 </xsl:template>
 <xsl:template match="NS2:ID[position() > 2]"/>
</xsl:stylesheet>

当应用于提供的 XML 文档时

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
    <soapenv:Body>
        <tns:send xmlns:tns="http://www.test.com/Service/v3">
            <NS2:Message release="006" version="010"
            xmlns:NS2="http://www.ncpdp.org/schema/SCRIPT">
                <NS2:Body>
                    <NS2:New>
                        <NS2:Pharmacy>
                            <NS2:Identification>
                                <NS2:ID>
                                    <NS2:IDValue>01017</NS2:IDValue>
                                    <NS2:IDQualifier>94</NS2:IDQualifier>
                                    <NS2:IDRegion>SCA</NS2:IDRegion>
                                    <NS2:IDState>CA</NS2:IDState>
                                </NS2:ID>
                                <NS2:ID>
                                    <NS2:IDValue>01018</NS2:IDValue>
                                    <NS2:IDQualifier>95</NS2:IDQualifier>
                                    <NS2:IDRegion>SCA</NS2:IDRegion>
                                    <NS2:IDState>CA</NS2:IDState>
                                </NS2:ID>
                                <NS2:ID>
                                    <NS2:IDValue>01019</NS2:IDValue>
                                    <NS2:IDQualifier>96</NS2:IDQualifier>
                                    <NS2:IDRegion>SCA</NS2:IDRegion>
                                    <NS2:IDState>CA</NS2:IDState>
                                </NS2:ID>
                            </NS2:Identification>
                        </NS2:Pharmacy>
                    </NS2:New>
                </NS2:Body>
            </NS2:Message>
        </tns:send>
    </soapenv:Body>
</soapenv:Envelope>

产生想要的正确结果

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <tns:send xmlns:tns="http://www.test.com/Service/v3">
         <NS2:Message xmlns:NS2="http://www.ncpdp.org/schema/SCRIPT" release="006" version="010">
            <NS2:Body>
               <NS2:New>
                  <NS2:Pharmacy>
                     <NS2:Identification>
                        <NS2:ID>
                           <NS2:IDValue>01017</NS2:IDValue>
                           <NS2:IDQualifier>94</NS2:IDQualifier>
                           <NS2:IDRegion>SCA</NS2:IDRegion>
                           <NS2:IDState>CA</NS2:IDState>
                        </NS2:ID>
                        <NS2:ID>
                           <NS2:IDValue>01018</NS2:IDValue>
                           <NS2:IDQualifier>95</NS2:IDQualifier>
                           <NS2:IDRegion>SCA</NS2:IDRegion>
                           <NS2:IDState>CA</NS2:IDState>
                        </NS2:ID>
                     </NS2:Identification>
                  </NS2:Pharmacy>
               </NS2:New>
            </NS2:Body>
         </NS2:Message>
      </tns:send>
   </soapenv:Body>
</soapenv:Envelope>

说明

正确使用和覆盖身份规则

更新

在评论中,OP 添加了一个新要求:每个NS2:IDRegion都必须被截断为两个字符。

这是实现新要求的更新转换:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  
 xmlns:NS2="http://www.ncpdp.org/schema/SCRIPT">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>
 <xsl:strip-space elements="*"/>

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

    <xsl:template match="NS2:IDRegion/text()">
      <xsl:value-of select="substring(.,1,2)"/>
    </xsl:template>
    <xsl:template match="NS2:ID[position() > 2]"/>
</xsl:stylesheet>

当此转换应用于同一个 XML 文档(如上)时,会产生所需的正确结果

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
   <soapenv:Body>
      <tns:send xmlns:tns="http://www.test.com/Service/v3">
         <NS2:Message xmlns:NS2="http://www.ncpdp.org/schema/SCRIPT" release="006" version="010">
            <NS2:Body>
               <NS2:New>
                  <NS2:Pharmacy>
                     <NS2:Identification>
                        <NS2:ID>
                           <NS2:IDValue>01017</NS2:IDValue>
                           <NS2:IDQualifier>94</NS2:IDQualifier>
                           <NS2:IDRegion>SC</NS2:IDRegion>
                           <NS2:IDState>CA</NS2:IDState>
                        </NS2:ID>
                        <NS2:ID>
                           <NS2:IDValue>01018</NS2:IDValue>
                           <NS2:IDQualifier>95</NS2:IDQualifier>
                           <NS2:IDRegion>SC</NS2:IDRegion>
                           <NS2:IDState>CA</NS2:IDState>
                        </NS2:ID>
                     </NS2:Identification>
                  </NS2:Pharmacy>
               </NS2:New>
            </NS2:Body>
         </NS2:Message>
      </tns:send>
   </soapenv:Body>
</soapenv:Envelope>
于 2012-10-18T18:45:22.003 回答