当前位置 : 主页 > 网页制作 > xml >

连接XML

来源:互联网 收集:自由互联 发布时间:2021-06-13
我有三个xml文件 stepProducts Product UserTypeID="Country" NameCyprus/Name Product UserTypeID="Resort" NameArgaka/Name Product UserTypeID="Property" NameVilla Tester/Name /Product /Product Product UserTypeID="Resort" NameCoral Bay/Name
我有三个xml文件

<step>
<Products>
    <Product UserTypeID="Country">
        <Name>Cyprus</Name>
        <Product UserTypeID="Resort">
            <Name>Argaka</Name>
            <Product UserTypeID="Property">
                <Name>Villa Tester</Name>
            </Product>
        </Product>
        <Product UserTypeID="Resort">
            <Name>Coral Bay</Name>
            <Product UserTypeID="Property">
                <Name>1</Name>
            </Product>
            <Product UserTypeID="Property">
                <Name>2</Name>
            </Product>
        </Product>
    </Product>
    <Product UserTypeID="Country">
        <Name>Greece</Name>
        <Product UserTypeID="Region">
            <Name>Corfu</Name>
            <Product UserTypeID="Resort">
                <Name>Aghios Stefanos</Name>
                <Product UserTypeID="Property">
                    <Name>Villa Joanna</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Villa Eleonas</Name>
                </Product>
            </Product>
            <Product UserTypeID="Resort">
                <Name>Kassiopi</Name>
                <Product UserTypeID="Property">
                    <Name>Villa 2</Name>
                </Product>
            </Product>
        </Product>
    </Product>
</Products>
<step>
<Products>
    <Product UserTypeID="Country">
        <Name>Cyprus</Name>
        <Product UserTypeID="Resort">
            <Name>Argaka</Name>
            <Product UserTypeID="Property">
                <Name>Villa Jaime</Name>
            </Product>
        </Product>
    </Product>
    <Product UserTypeID="Country">
        <Name>Greece</Name>
        <Product UserTypeID="Region">
            <Name>Corfu</Name>
            <Product UserTypeID="Resort">
                <Name>Acharavi</Name>
                <Product UserTypeID="Property">
                    <Name>Villa 1</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Villa 2</Name>
                </Product>
            </Product>
            <Product UserTypeID="Resort">
                <Name>Gouvia</Name>
                <Product UserTypeID="Property">
                    <Name>Villa De Bono</Name>
                </Product>
            </Product>
            <Product UserTypeID="Resort">
                <Name>Kassiopi</Name>
                <Product UserTypeID="Property">
                    <Name>Villa 1</Name>
                </Product>
            </Product>
        </Product>
    </Product>
</Products>
<step>
<Products>
    <Product UserTypeID="Country">
        <Name>Cyprus</Name>
        <Product UserTypeID="Resort">
            <Name>Aghia Marina</Name>
            <Product UserTypeID="Property">
                <Name>Villa Aghia Marina</Name>
            </Product>
        </Product>
        <Product UserTypeID="Resort">
            <Name>Coral Bay</Name>
            <Product UserTypeID="Property">
                <Name>Ascos Coral Villas</Name>
            </Product>
            <Product UserTypeID="Property">
                <Name>Coral Villa</Name>
            </Product>
            <Product UserTypeID="Property">
                <Name>Lella Villas</Name>
            </Product>
        </Product>
    </Product>
    <Product UserTypeID="Country">
        <Name>Greece</Name>
        <Product UserTypeID="Region">
            <Name>Corfu</Name>
            <Product UserTypeID="Resort">
                <Name>Acharavi</Name>
                <Product UserTypeID="Property">
                    <Name>Villa Angelos</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Villa Eleonas</Name>
                </Product>
            </Product>
            <Product UserTypeID="Resort">
                <Name>Aghios Stefanos</Name>
                <Product UserTypeID="Property">
                    <Name>Villa Joanna</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Villa Eleonas</Name>
                </Product>
            </Product>
            <Product UserTypeID="Resort">
                <Name>Kassiopi</Name>
                <Product UserTypeID="Property">
                    <Name>Villa Imerolia</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Test Property</Name>
                </Product>
            </Product>
        </Product>
    </Product>
</Products>

每个文件都有相同的产品(通过./name),但有不同的子产品(通过./name),我需要将它们连接成一个树,每个产品/名称有一个产品,包含相同规则的所有子产品,以便我可以输出一个结构.

我找到了一个xslt方法,它将创建一个如下所示的节点集

<xsl:variable name="step-output">
    <xsl:for-each select="/index/file">
        <xsl:copy-of select="document(.)" />
    </xsl:for-each>
</xsl:variable>
<xsl:variable name="step-products" select="exsl:node-set($step-output)//Products" />

但是,当我创建其他模板时,将按产品/名称创建三个产品,即塞浦路斯将出现三次.

有谁知道我怎么做我想要的?我的结果需要如下

<step>
<Products>
    <Product UserTypeID="Country">
        <Name>Cyprus</Name>
        <Product UserTypeID="Resort">
            <Name>Aghia Marina</Name>
            <Product UserTypeID="Property">
                <Name>Villa Aghia Marina</Name>
            </Product>
        </Product>
        <Product UserTypeID="Resort">
            <Name>Argaka</Name>
            <Product UserTypeID="Property">
                <Name>Villa Jaime</Name>
            </Product>
            <Product UserTypeID="Property">
                <Name>Villa Tester</Name>
            </Product>
        </Product>
        <Product UserTypeID="Resort">
            <Name>Coral Bay</Name>
            <Product UserTypeID="Property">
                <Name>Ascos Coral Villas</Name>
            </Product>
            <Product UserTypeID="Property">
                <Name>Coral Villa</Name>
            </Product>
            <Product UserTypeID="Property">
                <Name>Lella Villas</Name>
            </Product>
            <Product UserTypeID="Property">
                <Name>1</Name>
            </Product>
            <Product UserTypeID="Property">
                <Name>2</Name>
            </Product>
        </Product>
    </Product>
    <Product UserTypeID="Country">
        <Name>Greece</Name>
        <Product UserTypeID="Region">
            <Name>Corfu</Name>
            <Product UserTypeID="Resort">
                <Name>Acharavi</Name>
                <Product UserTypeID="Property">
                    <Name>Villa Angelos</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Villa Eleonas</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Villa 1</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Villa 2</Name>
                </Product>
            </Product>
            <Product UserTypeID="Resort">
                <Name>Aghios Stefanos</Name>
                <Product UserTypeID="Property">
                    <Name>Villa Joanna</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Villa Eleonas</Name>
                </Product>
            </Product>
            <Product UserTypeID="Resort">
                <Name>Gouvia</Name>
                <Product UserTypeID="Property">
                    <Name>Villa De Bono</Name>
                </Product>
            </Product>
            <Product UserTypeID="Resort">
                <Name>Kassiopi</Name>
                <Product UserTypeID="Property">
                    <Name>Villa Imerolia</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Test Property</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Villa 1</Name>
                </Product>
                <Product UserTypeID="Property">
                    <Name>Villa 2</Name>
                </Product>
            </Product>
        </Product>
    </Product>
</Products>
这是一个应该完成工作的XSLT 2.0样式表:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">

  <xsl:output indent="yes"/>

  <xsl:template match="/">
    <step>
      <Products>
        <xsl:for-each-group select="document(index/file)/step/Products/Product" group-by="Name">
          <Product UserTypeID="{@UserTypeID}">
            <Name><xsl:value-of select="current-grouping-key()"/></Name>
            <xsl:for-each-group select="current-group()/Product" group-by="Name">
              <xsl:sort select="current-grouping-key()"/>
              <Product UserTypeID="{@UserTypeID}">
                <Name><xsl:value-of select="current-grouping-key()"/></Name>
                <xsl:for-each select="current-group()/Product">
                  <xsl:sort select="Name"/>
                  <xsl:copy-of select="."/>
                </xsl:for-each>
              </Product>
            </xsl:for-each-group>
          </Product>
        </xsl:for-each-group>
      </Products>
    </step>
  </xsl:template>

</xsl:stylesheet>

您需要针对具有该结构的索引XML文档运行它

<index>
  <file>test2010020803.xml</file>
  <file>test2010020804.xml</file>
  <file>test2010020805.xml</file>
</index>

列出了您要处理的其他文件.

XSLT 2.0样式表可以用Saxon 9执行,它有.NET和Java版本,所以它可以在任何地方运行,至少Java 1.5或.NET 2.0可用或者可以安装.其他选项包括AltovaXML tools(仅限Windows)和Gestalt.

如果您绑定到XSLT 1.0,那么只要您有exsl:node-set或类似支持,就可以按如下方式执行:

<xsl:stylesheet
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:exsl="http://exslt.org/common"
  exclude-result-prefixes="exsl"
  version="1.0">

  <xsl:output indent="yes"/>
  <xsl:strip-space elements="*"/>

  <xsl:key name="k1" match="step/Products/Product" use="Name"/>
  <xsl:key name="k2" match="step/Products/Product/Product" use="concat(../Name, '|', Name)"/>

  <xsl:template match="/">
    <xsl:variable name="rtf">
      <xsl:copy-of select="document(index/file)/*"/>
    </xsl:variable>
    <step>
      <Products>
        <xsl:for-each select="exsl:node-set($rtf)/step/Products/Product[generate-id() = generate-id(key('k1', Name)[1])]">
          <Product UserTypeID="{@UserTypeID}">
            <xsl:copy-of select="Name"/>
            <xsl:for-each select="key('k1', Name)/Product[generate-id() = generate-id(key('k2', concat(../Name, '|', Name))[1])]">
              <xsl:sort select="Name"/>
              <Product UserTypeID="{@UserTypeID}">
                <xsl:copy-of select="Name"/>
                <xsl:for-each select="key('k2', concat(../Name, '|', Name))/Product">
                  <xsl:sort select="Name"/>
                  <xsl:copy-of select="."/>
                </xsl:for-each>
              </Product>
            </xsl:for-each>
          </Product>
        </xsl:for-each>
      </Products>
    </step>
  </xsl:template>

</xsl:stylesheet>

键看起来像这样:

<xsl:key name="k1" match="step/Products/Product" use="Name"/>

  <xsl:key name="k2" match="step/Products/Product/Product" use="concat(../Name, '|', Name)"/>

  <xsl:key name="k3" match="step/Products/Product/Product/Product"
                     use="concat(../../Name, '|', ../Name, '|', Name)"/>

  <xsl:key name="k4" 
           match="step/Products/Product/Product/Product/Product"
           use="concat(../../../Name, '|', ../../Name, '|', ../Name, '|', Name)"/>

  <xsl:key name="k5" 
           match="step/Products/Product/Product/Product/Product/Product"
           use="concat(../../../../Name, '|', ../../../Name, '|', ../../Name, '|', ../Name, '|', Name)"/>

  <xsl:key name="k6" 
           match="step/Products/Product/Product/Product/Product/Product/Product"
           use="concat(../../../../../Name, '|', ../../../../Name, '|', ../../../Name, '|', ../../Name, '|', ../Name, '|', Name)"/>

这些都直接在论坛编辑器中输入,因此可能有错误.

网友评论