-1

我有一个 XML 结构,其中 XML 架构不规则/未格式化。结构是这样的——

<Host> 
<element1>type0</element1>
<element2>Fruits</element2>
....
<elementn>Price0</elementn>   
   <Menu>
   <NodeA>
    <element1>type1</element1>
    <element2>Fruits</element2>
    ....
    <elementn>Price1</elementn>
    <Menu>
    <NodeB>
      <element1>type2</element1>
      <element2>Fruits</element2>
      ....
      <elementn>Price2</elementn>
      <Menu>
      <NodeC>
        <element1>type3</element1>
        <element2>Fruits</element2>
        ....
        <elementn>Price3</elementn>
        <Menu>
        <NodeD>
          <Element1>type4</element1>
          <Element2>Vegetables</Element2>
          ....
          <Elementn>Price4</elementn>  
        </NodeD>
        </Menu>    
      </NodeC>
      </Menu>
     </NodeB>
     </Menu>
  </NodeA>
  <NodeE>
    <element1>type5</element1>
    <element2>Fruits</element2>
    ....
    <elementn>Price5</elementn>
    <Menu>
    <NodeF>
      <element1>type6</element1>
      <element2>Vegetables</element2>
      ....
      <elementn>Price6</elementn>
    </NodeF> 
    </Menu>  
  </NodeE>  
  </Menu> 
</Host>

现在我预期的 XML 如下 -

a)如果<element2>== 所有节点中的水果,我需要如下 XML 模式。我可以在主机下方包含或排除以下 n 个元素 -

`<element1>type0</element>
 <element2>Fruits</element2>
 ....
 <elementn>Price0</elementn>`

。预期结果 -

<Host> 
  <NodeA>
    <element1>type1</element1>
    <element2>Fruits</element2>
    ....
    <elementn>Price1</elementn>
  </NodeA>
  <NodeB>
    <element1>type2</element1>
    <element2>Fruits</element2>
    ....
    <elementn>Price2</elementn>
  </NodeB>
  <NodeC>
    <element1>type3</element1>
    <element2>Fruits</element2>
    ....
    <elementn>Price3</elementn>
  </NodeC>
  <NodeE>
    <element1>type5</element1>
    <element2>Fruits</element2>
    ....
    <elementn>Price5</elementn>
  </NodeE>    
</Host>

b)如果<element2>== 所有节点中的蔬菜,我需要如下 XML 模式

注意:<element2>==蔬菜总是在模式中的最后一个节点

<Host>
  <NodeD>
    <element1>type4</element1>
    <element2>Vegetables</element2>
    ....
    <elementn>Price4</elementn>
  </NodeD>    
  <NodeF>
    <element1>type6</element1>
    <element2>Vegetables</element2>
    ....
    <elementn>Price6</elementn>
  </NodeF>
</Host>

通过 XSLT 获得上述 XML 格式的任何帮助都将是一个很大的帮助。

4

1 回答 1

2

如果您想要 2 个单独的文档,则实际上不需要 2 个 XSLT。您可以使用一个 XSLT 但带有一个参数

<xsl:param name="element2" select="'Fruits'" />

(这里'Fruits'只是默认值,如果调用应用程序没有指定参数)。

您将从选择与参数相等的节点开始element2(请注意 XML 和 XSLT 区分大小写,因此element2Element2您的 XML 中的不同,但我认为这是您的 XML 中的拼写错误)。

<xsl:apply-templates select="//*[element2=$element2]"/>

您还需要一个模板来确保节点匹配时,它不会复制子节点......

<xsl:template match="*[element2]">
    <xsl:copy>
        <xsl:apply-templates select="*[not(*)]" />
    </xsl:copy>
</xsl:template>

其他节点将由身份模板处理。

试试这个 XSLT...

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:param name="element2" select="'Fruits'" />

    <xsl:template match="/*">
        <xsl:copy>
            <xsl:apply-templates select="//*[element2=$element2]" mode="copy"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="*[element2]" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="*[not(*)]" mode="copy"/>
        </xsl:copy>
    </xsl:template>

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

请注意,如果您使用的是 XSLT 2.0,您可以在一次调用中创建多个文档,xsl:for-each-group用于获取不同的组,并xsl:result-document为每个组创建一个文件。

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" indent="yes" />

    <xsl:template match="/*">
        <xsl:for-each-group select="//*[element2]" group-by="element2">
            <xsl:result-document href="{current-grouping-key()}.xml" method="xml">
                <Host>
                    <xsl:apply-templates select="current-group()" mode="copy" />
                </Host>
            </xsl:result-document>
        </xsl:for-each-group>
    </xsl:template>

    <xsl:template match="*[element2]" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="*[not(*)]" mode="copy"/>
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@*|node()" mode="copy">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" mode="copy" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>
于 2017-03-09T11:13:47.317 回答