使用<xsl:sort>基于节点值对XML进行排序,并更改元素名称问题</xsl:sort>

时间:2014-05-30 11:54:50

标签: xml xslt xslt-2.0

我尝试根据给定xml的值对XML进行排序。从请求xml我需要基于education_details排序{DR,PDR,MSC,BSC}。我用过。请参阅下面的示例。

输入xml

<?xml version="1.0" encoding="UTF-8"?>
<root>
       <document>
         <studentname>ACM</studentname>
         <educational_details>MSC</educational_details>
       </document>
       <document>
         <studentname>ACB</studentname>
         <educational_details>BSc</educational_details>
       </document>
       <document>
         <studentname>ACP</studentname>
         <educational_details>PDR</educational_details>
       </document>
       <document>
         <studentname>ACC</studentname>
         <educational_details>DR</educational_details>
       </document>
</root>

转换XSLT

<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:param name="pOrder" select="'DR,PDR,MSC,BSc'" />

        <xsl:variable name="vSequence" select="tokenize($pOrder, ',')"/>

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

        <xsl:template match="root">
            <xsl:copy>
                <xsl:apply-templates select="document">
                    <xsl:sort
                        select="index-of($vSequence, educational_details)" />
                </xsl:apply-templates>
            </xsl:copy>
        </xsl:template>

    </xsl:stylesheet>

查找xml

<?xml version="1.0" encoding="UTF-8"?>
<lookups>
    <lookup tc="13" responce="Doctor" request="DR" />   
    <lookup tc="12" responce="Post DR" request="PDR" />
    <lookup tc="30" responce="Master of Scienc" request="MSc" />    
    <lookup tc="4" responce="Bachelor of Science" request="BSc" />
</lookups>

输出xml

  <?xml version="1.0" encoding="UTF-8"?>
        <root>
               <document>
                 <studentname>ACM</studentname>
                 <stu_educational_details tc="30">Master of Scienc</stu_educational_details>
               </document>
               <document>
                 <studentname>ACB</studentname>
                 <stu_educational_details tc="4">Bachelor of Science</stu_educational_details>
               </document>
               <document>
                 <studentname>ACP</studentname>
                 <stu_educational_details tc="12">Post DR</stu_educational_details>
               </document>
               <document>
                 <studentname>ACC</studentname>
                 <stu_educational_details tc="13">Doctor</stu_educational_details>
               </document>
        </root>

预期输出

 <?xml version="1.0" encoding="UTF-8"?>
            <root>
                  <document>
                     <studentname>ACC</studentname>
                     <stu_educational_details tc="13">Doctor</stu_educational_details>
                   </document>
                   <document>
                     <studentname>ACP</studentname>
                     <stu_educational_details tc="12">Post DR</stu_educational_details>
                   </document>
                   <document>
                     <studentname>ACM</studentname>
                     <stu_educational_details tc="30">Master of Scienc</stu_educational_details>
                   </document>
                   <document>
                     <studentname>ACB</studentname>
                     <stu_educational_details tc="4">Bachelor of Science</stu_educational_details>
                   </document>
              </root>

我编写了更改元素和值名称的逻辑。

1 个答案:

答案 0 :(得分:2)

您发布的样式表是我建议作为对您之前问题的回复,它会进行排序,但它不会产生您想要的重命名和替换。

重命名很容易添加:

<xsl:stylesheet version="2.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:param name="pOrder" select="'DR,PDR,MSC,BSc'" />

        <xsl:variable name="vSequence" select="tokenize($pOrder, ',')"/>

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

        <xsl:template match="root">
            <xsl:copy>
                <xsl:apply-templates select="document">
                    <xsl:sort
                        select="index-of($vSequence, educational_details)" />
                </xsl:apply-templates>
            </xsl:copy>
        </xsl:template>

        <xsl:template match="educational_details">
          <stu_educational_details>
            <xsl:value-of select="."/>
          </stu_educational_details>
        </xsl:template>

    </xsl:stylesheet>

至于添加属性并替换"DR"等代码,您至少需要向我们展示tc数字和"Doctor"等替换字符串等数据来自何处。通常,人们会使用查找文档,只需使用键来查找值。

这是一个带有用于查找的键的编辑:

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

        <xsl:param name="lookup-url" select="'test2014053002.xml'"/>

        <xsl:variable name="lookup-doc" select="doc($lookup-url)"/>

        <xsl:param name="pOrder" select="'DR,PDR,MSC,BSc'" />

        <xsl:variable name="vSequence" select="tokenize($pOrder, ',')"/>

        <xsl:key name="codes" match="lookup" use="@request"/>

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

        <xsl:template match="root">
            <xsl:copy>
                <xsl:apply-templates select="document">
                    <xsl:sort
                        select="index-of($vSequence, educational_details)" />
                </xsl:apply-templates>
            </xsl:copy>
        </xsl:template>

        <xsl:template match="educational_details">
          <stu_educational_details tc="{key('codes', ., $lookup-doc)/@tc}">
            <xsl:value-of select="key('codes', ., $lookup-doc)/@responce"/>
          </stu_educational_details>
        </xsl:template>

    </xsl:stylesheet>

请注意,目前您的示例使用不同的拼写(responce而非response),request属性值和部分示例数据中的字母不同,您可能会需要规范化拼写,或者您需要添加<xsl:key name="codes" match="lookup" use="upper-case(@request)"/>key('codes', upper-case(.), $lookup-doc)