1

我需要将 XML 从一种结构转换为另一种结构。我不知道该怎么做。第一个 xml 看起来并不像主细节,但结果需要看起来像桅杆细节。

   <?xml version = '1.0' encoding = 'UTF-8'?>
    <Root-Element xmlns="http://example.com/ReadProductB">
       <RECORD1>
          <C2>QGGG9.A1-1</C2>
       </RECORD1>
       <RECORD2>
          <C2>xflowcode</C2>
          <C3>FL1</C3>
       </RECORD2>
       <RECORD2>
          <C2>xtilo</C2>
          <C3>1234</C3>
       </RECORD2>
       <RECORD2>
          <C2>xwat</C2>
          <C3>75</C3>
       </RECORD2>
       <RECORD1>
          <C2>QGGG9.A1-2</C2>
       </RECORD1>
       <RECORD2>
          <C2>xflowcode</C2>
          <C3>FL1</C3>
       </RECORD2>
       <RECORD2>
          <C2>xtilo</C2>
          <C3>1234</C3>
       </RECORD2>
       <RECORD2>
          <C2>xwat</C2>
          <C3>75</C3>
       </RECORD2>
    </Root-Element>

这就是我想要的结果。

   <?xml version = '1.0' encoding = 'UTF-8'?>
    <ns0:ProductCollection xmlns:ns0="http://example.com/ReadProductBB" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <ns0:RECORD1>
          <ns0:C2>QGGG9.A1-1</ns0:C2>
          <ns0:RECORD2Collection>
             <ns0:RECORD2>
                <ns0:C2>xflowcode</ns0:C2>
                <ns0:C3>FL1</ns0:C3>
             </ns0:RECORD2>
             <ns0:RECORD2>
                <ns0:C2>xtilo</ns0:C2>
                <ns0:C3>1234</ns0:C3>
             </ns0:RECORD2>
             <ns0:RECORD2>
                <ns0:C2>xwat</ns0:C2>
                <ns0:C3>75</ns0:C3>
             </ns0:RECORD2>
          </ns0:RECORD2Collection>
       </ns0:RECORD1>
       <ns0:RECORD1>
          <ns0:C2>QGGG9.A1-2</ns0:C2>
          <ns0:RECORD2Collection>
             <ns0:RECORD2>
                <ns0:C2>xflowcode</ns0:C2>
                <ns0:C3>FL1</ns0:C3>
             </ns0:RECORD2>
             <ns0:RECORD2>
                <ns0:C2>xtilo</ns0:C2>
                <ns0:C3>1234</ns0:C3>
             </ns0:RECORD2>
             <ns0:RECORD2>
                <ns0:C2>xwat</ns0:C2>
                <ns0:C3>75</ns0:C3>
             </ns0:RECORD2>
          </ns0:RECORD2Collection>
       </ns0:RECORD1>
    </ns0:ProductCollection>

请帮忙。谢谢

4

2 回答 2

1

此样式表使用通用模板将原始元素移动到命名空间中的同名元素ns0

RECORD2元素与其对应的RECORD1元素配对,使用generate-id标识当前RECORD1,然后处理RECORD2其前一个RECORD1元素具有相同 id 的所有后续元素。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
    xmlns:src="http://example.com/ReadProductB"
    xmlns:ns0="http://example.com/ReadProductBB"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    exclude-result-prefixes="src"
    version="1.0">

    <xsl:strip-space elements="*"/>
    <xsl:output method="xml" indent="yes" encoding="UTF-8"/>

    <xsl:template match="/src:Root-Element">
        <ns0:ProductCollection>
            <xsl:apply-templates select="src:RECORD1"/>
        </ns0:ProductCollection>
    </xsl:template>

    <xsl:template match="src:RECORD1">
        <ns0:RECORD1>
            <xsl:apply-templates/>
            <xsl:variable name="record1" select="generate-id()"/>
            <ns0:RECORD2Collection>
                <xsl:for-each select="following-sibling::src:RECORD2">
                    <xsl:if test="generate-id(preceding-sibling::src:RECORD1[1]) = $record1">
                        <xsl:apply-templates select="."/>
                    </xsl:if>
                </xsl:for-each>
            </ns0:RECORD2Collection>
        </ns0:RECORD1>
    </xsl:template>

    <xsl:template match="*">
        <xsl:element name="ns0:{local-name(current())}">
            <xsl:apply-templates/>
        </xsl:element>
    </xsl:template>

</xsl:stylesheet>

输出

<?xml version="1.0" encoding="UTF-8"?>
<ns0:ProductCollection xmlns:ns0="http://example.com/ReadProductBB" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <ns0:RECORD1>
      <ns0:C2>QGGG9.A1-1</ns0:C2>
      <ns0:RECORD2Collection>
         <ns0:RECORD2>
            <ns0:C2>xflowcode</ns0:C2>
            <ns0:C3>FL1</ns0:C3>
         </ns0:RECORD2>
         <ns0:RECORD2>
            <ns0:C2>xtilo</ns0:C2>
            <ns0:C3>1234</ns0:C3>
         </ns0:RECORD2>
         <ns0:RECORD2>
            <ns0:C2>xwat</ns0:C2>
            <ns0:C3>75</ns0:C3>
         </ns0:RECORD2>
      </ns0:RECORD2Collection>
   </ns0:RECORD1>
   <ns0:RECORD1>
      <ns0:C2>QGGG9.A1-2</ns0:C2>
      <ns0:RECORD2Collection>
         <ns0:RECORD2>
            <ns0:C2>xflowcode</ns0:C2>
            <ns0:C3>FL1</ns0:C3>
         </ns0:RECORD2>
         <ns0:RECORD2>
            <ns0:C2>xtilo</ns0:C2>
            <ns0:C3>1234</ns0:C3>
         </ns0:RECORD2>
         <ns0:RECORD2>
            <ns0:C2>xwat</ns0:C2>
            <ns0:C3>75</ns0:C3>
         </ns0:RECORD2>
      </ns0:RECORD2Collection>
   </ns0:RECORD1>
</ns0:ProductCollection>
于 2013-05-05T18:47:13.133 回答
0
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:b="http://example.com/ReadProductB"
    xmlns:bb="http://example.com/ReadProductBB"
    version="1.0">
    <xsl:output indent="yes"/>

    <!--
        identity template
        https://en.wikipedia.org/wiki/Identity_transform
    -->
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>

    <!--
        converts elements from the namespace "http://example.com/ReadProductB"
        to "http://example.com/ReadProductBB" 
    -->
    <xsl:template match="b:*">
        <xsl:element name="bb:{local-name()}">
            <xsl:apply-templates select="@*|node()"/>
        </xsl:element>
    </xsl:template>

    <xsl:template match="b:Root-Element">  
        <!--Convert b:Root-Element into bb:ProductCollection-->
        <bb:ProductCollection>
            <!--and then "push" only the b:RECORD1 elements -->
            <xsl:apply-templates select="b:RECORD1"/>
        </bb:ProductCollection>
    </xsl:template>

    <xsl:template match="b:RECORD1">
        <!--Convert the RECORD1 to new namespace -->
        <bb:RECORD1>
            <!-- "push" it's children 
            (which will match the generic templates above)-->
            <xsl:apply-templates select="@*|node()"/>
            <bb:RECORD2Collection>
              <!--and "push" the RECORD2 elements that are 
                between this RECORD1 element and the next(or the end) -->
              <xsl:apply-templates select="following-sibling::b:RECORD2
                      [generate-id(preceding-sibling::b:RECORD1[1])
                       = generate-id(current())]" />
            </bb:RECORD2Collection>
        </bb:RECORD1>
    </xsl:template>

</xsl:stylesheet>
于 2013-05-05T14:38:52.687 回答