从xsl转换创建多个xmls,并根据source xml的标记属性将数据放入那些xml中

时间:2012-09-14 17:13:30

标签: xml xslt xpath xslt-2.0

我尝试使用xsl 2.0基于语言名称创建不同的xml文件。在我输入的xml中,这里只有2种语言," en"和" es"。

  1. 所有" en"基础人员将转到en.xml和
  2. 所有" es"基础人员将转到es.xml和
  3. 所有同时拥有" en"和" es"必须同时使用en.xml和es.xml。
  4. 我的输入XML: source xml是关于人员,他们的地址和语言的列表

    <persons>
        <person name="Alice">
            <Addresses>
                <Address type ="personal">
                    <language name = "en">
                    </language>
                </Address>
                <Address type ="business">
                    <language name = "en">
                    </language>
                </Address>
            </Addresses>
        </person>
        <person name="Bob">
            <Addresses>
                <Address type ="personal">
                    <language name = "es">
                    </language>
                </Address>
                <Address type ="business">
                    <language name = "es">
                    </language>
                </Address>
            </Addresses>
        </person>
        <person name="Stacy">
            <Addresses>
                <Address type ="personal">
                    <language name = "en">
                    </language>
                </Address>
                <Address type ="business">
                    <language name = "es">
                    </language>
                </Address>
            </Addresses>
        </person>
    </persons>
    

    输出文件en.xml将包含:

    所有包含语言属性值=&#34; en&#34;应该转到en.xml文件。在这种情况下,Alice和Stacy都需要转到en.xml

        <person name="Alice">
            <Addresses>
                <Address type ="personal">
                    <language name = "en">
                    </language>
                </Address>
                <Address type ="business">
                    <language name = "en">
                    </language>
                </Address>
            </Addresses>
        </person>
            <person name="Stacy">
            <Addresses>
                <Address type ="personal">
                    <language name = "en">
                    </language>
                </Address>
                <Address type ="business">
                    <language name = "es">
                    </language>
                </Address>
            </Addresses>
        </person>
    

    输出文件es.xml将具有:

    所有包含语言属性值=&#34; es&#34;应该转到en.xml文件。在这种情况下,Bob和Stacy都需要转到es.xml

        <person name="Bob">
            <Addresses>
                <Address type ="personal">
                    <language name = "es">
                    </language>
                </Address>
                <Address type ="business">
                    <language name = "es">
                    </language>
                </Address>
            </Addresses>
        </person>
        <person name="Stacy">
            <Addresses>
                <Address type ="personal">
                    <language name = "en">
                    </language>
                </Address>
                <Address type ="business">
                    <language name = "es">
                    </language>
                </Address>
            </Addresses>
        </person>
    

    到目前为止我的XSL:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet 
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
      version="2.0">
    
    <xsl:output method="xml" indent="yes" name="xml"/>
    
    <xsl:template match="/">
        <xsl:for-each select="//persons">
           <xsl:variable name="filename"
                 select="concat('allpersons/',//persons/person/Addresses/Address/language/@name,'.xml')" />
           <xsl:value-of select="$filename" />  <!-- Creating  -->
           <xsl:result-document href="{$filename}" format="xml">
                 <xsl:value-of select="."/>
           </xsl:result-document>
         </xsl:for-each>
    </xsl:template>
    </xsl:stylesheet>
    

    解决方案不应包含属性的静态匹配,例如&#34; en&#34;,&#34; es&#34; ..因为有很多语言。任何帮助都很受欢迎?

    参考文献: http://www.ibm.com/developerworks/xml/library/x-tipmultxsl/index.html

1 个答案:

答案 0 :(得分:1)

这是一个XSLT 2.0示例:

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

<xsl:output indent="yes"/>

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

<xsl:template match="persons">
  <xsl:for-each-group select="person" group-by="Addresses/Address/language/@name">
    <xsl:result-document href="{current-grouping-key()}.xml">
      <xsl:apply-templates select="current-group()"/>
    </xsl:result-document>
  </xsl:for-each-group>
</xsl:template>

<xsl:template match="person/Addresses">
  <xsl:if test="Address/language/@name = current-grouping-key()">
    <xsl:next-match/>
  </xsl:if>
</xsl:template>

</xsl:stylesheet>

我不确定您是否真的想要在没有root的情况下创建这些结果文件,但如果您想要将persons模板更改为

<xsl:template match="persons">
  <xsl:for-each-group select="person" group-by="Addresses/Address/language/@name">
    <xsl:result-document href="{current-grouping-key()}.xml">
      <persons>
        <xsl:apply-templates select="current-group()"/>
      </persons>
    </xsl:result-document>
  </xsl:for-each-group>
</xsl:template>