通过xpath列表创建xml文件

时间:2016-09-19 00:23:53

标签: xslt

我有一个xpath的源列表和目标列表,其中每个列表都基于它们自己的架构。对于每个源路径,存在目标路径。例如,我有源列表[/ shiporder / shipfrom / name,/ shiporder / address / city]和目标列表[/ root / Seller / Country,/ root / Seller / City],其中列表的顺序连接源-path与目标路径。现在我可以创建简单且易读的样式表,它们应用每个源路径并创建相对于目标路径的输出。对于/ shiporder / shipfrom / name,stylesheet为:

<xsl:template match="/">
        <xsl:apply-templates select="shiporder"/>
  </xsl:template>
 <xsl:template match="/shiporder">
 <root>
        <xsl:apply-templates select="shipfrom"/>
 </root>
 </xsl:template>
<xsl:template match="/shiporder/shipfrom">
    <Seller>
        <xsl:apply-templates select="name"/>
    </Seller>
 </xsl:template>
<xsl:template match="/shiporder/shipfrom/name">
    <Country>
        <xsl:apply-templates select="text()"/>
    </Country>
</xsl:template>

/shiporder/address/city stylesheet是:

  <xsl:template match="/">
        <xsl:apply-templates select="shiporder"/>
  </xsl:template> 
 <xsl:template match="/shiporder">
 <root>
        <xsl:apply-templates select="address"/>
 </root>
 </xsl:template>
<xsl:template match="/shiporder/address">
    <Seller>
        <xsl:apply-templates select="city"/>        
    </Seller>
 </xsl:template>
 <xsl:template match="/shiporder/address/city">
    <City>
        <xsl:apply-templates select="text()"/>
    </City>
 </xsl:template>

创建后,我根据源模式将两个样式表应用于任意源xml文件,例如:

<shiporder>
  <shipfrom>
    <name>orderperson1</name>
  </shipfrom>
  <address>
    <city>London</city>
  </address>
  <address>
    <city>Berlin</city>
  </address>
</shiporder>

现在我想将两个样式表尽可能简单地合并到一个stylesheet

2 个答案:

答案 0 :(得分:0)

根据我在你的问题中所理解的,我想出了类似的东西:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="2.0">

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

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

    <xsl:template match="shiporder">
        <root>
            <xsl:apply-templates/>
        </root>
    </xsl:template>

    <xsl:template match="address">
        <!-- store the name node to a variable -->
        <xsl:variable name="country" select="../shipfrom/name"/>
        <Seller>
            <xsl:apply-templates/>
            <!-- check if the variable is not empty,
                 if not, output the contents under the node Country -->
            <xsl:if test="normalize-space($country)!=''">
                <Country>
                    <xsl:value-of select="$country"/>
                </Country>
            </xsl:if>
        </Seller>
    </xsl:template>

    <xsl:template match="city">
        <City>
            <xsl:apply-templates/>
        </City>
    </xsl:template>

    <xsl:template match="shipfrom">
        <xsl:choose>
            <!-- check for following-sibling address nodes, 
                 if none found, delete the node -->
            <xsl:when test="following-sibling::address"/>
            <xsl:otherwise>
                <Seller>
                    <xsl:apply-templates/>
                </Seller>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>

    <xsl:template match="shipfrom/name">
        <Country>
            <xsl:apply-templates/>
        </Country>
    </xsl:template>

</xsl:stylesheet>

答案 1 :(得分:0)

您的第一个样式表输出以下XML文件:

<?xml version="1.0" encoding="utf-8"?>
<root>
   <Seller>
      <Country>orderperson1</Country>
   </Seller>
</root>

此外,您的第二个样式表输出以下XML文件:

<?xml version="1.0" encoding="utf-8"?>
<root>
   <Seller>
      <City>London</City>
   </Seller>
   <Seller>
      <City>Berlin</City>
   </Seller>
</root>

如果要通过一个样式表模块生成两个输出结果,则应引入控制输出的参数xsl:param。我制作了实现此要求的最小样式表。

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">

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

    <xsl:param name="prmOutputShipForm" select="'yes'"/>
    <xsl:variable name="pOutputShipForm" select="$prmOutputShipForm = 'yes'"/>

    <xsl:template match="/">
        <xsl:apply-templates select="shiporder"/>
    </xsl:template>

    <xsl:template match="/shiporder">
        <root>
            <xsl:choose>
                <xsl:when test="$pOutputShipForm">
                    <xsl:apply-templates select="shipfrom"/>
                </xsl:when>
                <xsl:otherwise>
                    <xsl:apply-templates select="address"/>
                </xsl:otherwise>
            </xsl:choose>
        </root>
    </xsl:template>

    <xsl:template match="/shiporder/shipfrom">
        <Seller>
            <xsl:apply-templates select="name"/>
        </Seller>
    </xsl:template>

    <xsl:template match="/shiporder/shipfrom/name">
        <Country>
            <xsl:apply-templates/>
        </Country>
    </xsl:template>

    <xsl:template match="/shiporder/address">
        <Seller>
            <xsl:apply-templates select="city"/>        
        </Seller>
    </xsl:template>

    <xsl:template match="/shiporder/address/city">
        <City>
            <xsl:apply-templates/>
        </City>
    </xsl:template>

</xsl:stylesheet>

通过设置OutputShipForm =&#34; yes / no&#34;,您可以控制输出XML结果。