初学者 - 用xslt转换xml(添加父节点)

时间:2018-02-23 12:14:12

标签: xml xslt

好吧,

XML看起来像这样:

SELECT id as id, formid as formid, proposerid as proposerid, fieldid as 
       fieldid, response as response, remarks as remarks, listId as listId, 
       isMarked as isMarked FROM responsemaster WHERE formid = 40066 AND proposerid = '7ca6533a-c5f0-43e2-9980-83f9ae2c7370201802230113550000' 
       GROUP BY fieldid HAVING fieldid = MIN(fieldid)

XSLT目前看起来像这样:

<?xml version="1.0" encoding="UTF-8"?>
<Order_Root>
   <Header Info="Some Info" Info2="More Info" Info3="More Info">
   <Order Number="1" Date="1/23/2018 10:53:00 AM">
      <OrderCharges Charge="0.00000" />
   </Order>
   <Order Number="2" Date="1/23/2018 10:53:00 AM">
      <OrderCharges Charge="0.00000" />
   </Order>
   <Order Number="3" Date="1/23/2018 10:53:00 AM">
      <OrderCharges Charge="0.00000" />
   </Order>
   </Header>
</Order_Root>

目前的结果如下:

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

    <xsl:template match="Order">
        <xsl:variable name="url">
           <xsl:value-of select="@Number"/>
            <xsl:text>.xml</xsl:text> 
        </xsl:variable>
        <xsl:result-document method="xml" href="{$url}">
            <SplitOrder>
                <xsl:copy-of select="parent::node()/Header"></xsl:copy-of>
                <xsl:copy-of select="." />
            </SplitOrder>
        </xsl:result-document>
    </xsl:template>

</xsl:stylesheet>

我已经尝试了几个小时,但没有运气试图在所有三个输出xml上获取标题信息。我非常喜欢xslt的初学者,感谢任何帮助。我使用的是Saxon xsl 2.0版。 导致:

<?xml version="1.0" encoding="UTF-8"?>
<SplitOrder>
   <Order Number="1" Date="1/23/2018 10:53:00 AM">
      <OrderCharges Charge="0.00000"/>
   </Order>
</SplitOrder>

<?xml version="1.0" encoding="UTF-8"?>
<SplitOrder>
   <Order Number="2" Date="1/23/2018 10:53:00 AM">
      <OrderCharges Charge="0.00000"/>
   </Order>
</SplitOrder>

<?xml version="1.0" encoding="UTF-8"?>
<SplitOrder>
   <Order Number="3" Date="1/23/2018 10:53:00 AM">
      <OrderCharges Charge="0.00000"/>
   </Order>
</SplitOrder>

2 个答案:

答案 0 :(得分:0)

Header实际上是匹配的Order节点的父级。您可以执行xsl:copy-of select=".." />但最终也会复制所有子Order节点。

相反,创建一个新节点并复制属性,如此......

    <xsl:result-document method="xml" href="{$url}">
        <SplitOrder>
            <Header>
                <xsl:copy-of select="../@*" />
                <xsl:copy-of select="." />
            </Header>
        </SplitOrder>
    </xsl:result-document>

答案 1 :(得分:0)

对于一般方法,您可以通过一种模式运行包含Order的子树,该模式确保只复制它的祖先:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

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

    <xsl:template match="Order">
            <SplitOrder>
                <xsl:apply-templates select="/*/*" mode="subtree">
                  <xsl:with-param name="subtree" select="ancestor-or-self::*[position() ne last()]" tunnel="yes"/>
                </xsl:apply-templates>
            </SplitOrder>
    </xsl:template>

    <xsl:template match="*" mode="subtree">
        <xsl:param name="subtree" tunnel="yes"/>
        <xsl:if test=". intersect $subtree">
            <xsl:copy>
                <xsl:copy-of select="@*"/>
                <xsl:apply-templates mode="subtree"/>
            </xsl:copy>
        </xsl:if>
    </xsl:template>

    <xsl:template match="Order" mode="subtree">
        <xsl:param name="subtree" tunnel="yes"/>
        <xsl:copy-of select=".[. intersect $subtree]"/>
    </xsl:template>

</xsl:stylesheet>

请注意,上面没有xsl:result-document,但您当然可以将其添加回来。例如

    <xsl:template match="Order">
         <xsl:result-document href="{@Number}.xml">
            <SplitOrder>
                <xsl:apply-templates select="/*/*" mode="subtree">
                  <xsl:with-param name="subtree" select="ancestor-or-self::*[position() ne last()]" tunnel="yes"/>
                </xsl:apply-templates>
            </SplitOrder>
         </xsl:result-document>
    </xsl:template>