【问题标题】:XSLT to Transform XML into Hierarchial FormatXSLT 将 XML 转换为分层格式
【发布时间】:2015-08-30 20:54:31
【问题描述】:

我有一个简单形式的包含 partyId 和 parentPartyId 值的 xml。我想把它转换成层次树格式的形式。

我已根据所需的输出创建了架构。我正在http://www.keller.com/xslt/8/ 中尝试轴名称表达式。我没有得到,如何将源转换为所需的格式?

Source和需要的Target如下。

来源:

<OutputCollection xmlns="http://xmlns.test.com/pcbpel/adapter/db/PartyHierarchy">
            <Output>
               <level>1</level>
               <Parent_Party xsi:nil="true"/>
               <Party>Party-1</Party>
            </Output>
            <Output>
               <level>2</level>
               <Parent_Party>Party-1</Parent_Party>
               <Party>Party-1-1</Party>
            </Output>
            <Output>
               <level>2</level>
               <Parent_Party>Party-1</Parent_Party>
               <Party>Party-1-2</Party>
            </Output>
            <Output>
               <level>3</level>
               <Parent_Party>Party-1-2</Parent_Party>
               <Party>Party-1-2-1</Party>
            </Output>
            <Output>
               <level>3</level>
               <Parent_Party>Party-1-2</Parent_Party>
               <Party>Party-1-2-2</Party>
            </Output>
            <Output>
               <level>3</level>
               <Parent_Party>Party-1-2</Parent_Party>
               <Party>Party-1-2-3</Party>
            </Output>
            <Output>
               <level>2</level>
               <Parent_Party>Party-1</Parent_Party>
               <Party>Party-1-3</Party>
            </Output>
            <Output>
               <level>3</level>
               <Parent_Party>Party-1-3</Parent_Party>
               <Party>Party-1-3-1</Party>
            </Output>
            <Output>
               <level>3</level>
               <Parent_Party>Party-1-3</Parent_Party>
               <Party>Party-1-3-2</Party>
            </Output>
         </OutputCollection>

目标:

<OutputCollection xmlns="http://xmlns.test.com/pcbpel/adapter/db/PartyHierarchy">
            <Output>
               <level>1</level>
               <Parent_Party xsi:nil="true"/>
               <Party>Party-1</Party>
               <Children>
                    <level>2</level>
                    <Parent_Party>Party-1</Parent_Party>
                    <Party>Party-1-1</Party>
               </Children>
               <Children>
                    <level>2</level>
                    <Parent_Party>Party-1</Parent_Party>
                    <Party>Party-1-2</Party>
                    <Children>
                        <level>3</level>
                        <Parent_Party>Party-1-2</Parent_Party>
                        <Party>Party-1-2-1</Party>
                    </Children>
                    <Children>
                        <level>3</level>
                        <Parent_Party>Party-1-2</Parent_Party>
                        <Party>Party-1-2-2</Party>
                    </Children>
                    <Children>
                        <level>3</level>
                        <Parent_Party>Party-1-2</Parent_Party>
                        <Party>Party-1-2-3</Party>                  
                    </Children>
               </Children>
               <Children>
                    <level>2</level>
                    <Parent_Party>Party-1</Parent_Party>
                    <Party>Party-1-3</Party>
                    <Children>
                        <level>3</level>
                        <Parent_Party>Party-1-3</Parent_Party>
                        <Party>Party-1-3-1</Party>                  
                    </Children>
                    <Children>
                        <level>3</level>
                        <Parent_Party>Party-1-3</Parent_Party>
                        <Party>Party-1-3-2</Party>          
                    </Children>                 
               </Children>
            </Output>
         </OutputCollection>

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    对于 XSLT,如果您需要遵循交叉引用,那么您需要定义一个键 &lt;xsl:key name="children" match="ph:Output" use="ph:Parent_Party"/&gt; 并使用它 &lt;xsl:apply-templates select="key('children', ph:Party)"/&gt;

    <xsl:stylesheet
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:ph="http://xmlns.test.com/pcbpel/adapter/db/PartyHierarchy"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns="http://xmlns.test.com/pcbpel/adapter/db/PartyHierarchy"
      exclude-result-prefixes="ph xsi"
      version="1.0">
    
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>
    
    <xsl:key name="children" match="ph:Output" use="ph:Parent_Party"/>
    
    <xsl:template match="/*">
      <xsl:copy>
        <xsl:apply-templates select="key('children', '')"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="ph:Output[ph:Parent_Party/@xsi:nil = 'true']">
      <xsl:copy>
        <xsl:copy-of select="node()"/>
        <xsl:apply-templates select="key('children', ph:Party)"/>
      </xsl:copy>
    </xsl:template>
    
    <xsl:template match="ph:Output">
      <children>
        <xsl:copy-of select="node()"/>
        <xsl:apply-templates select="key('children', ph:Party)"/>
      </children>
    </xsl:template>
    
    </xsl:stylesheet>
    

    请注意,您发布的输入示例使用前缀 xsi,但未声明它,因此我必须为该前缀假设一个命名空间。

    【讨论】:

    • 非常感谢,马丁!我花了很多时间来关注、关注等等,但是这个解决方案很有效并且非常简洁。我是高级 XSLT 的新手。您能否建议任何概念或类似问题的实践链接?
    • 有一个FAQ汇编dpawson.co.uk/xsl/sect2/sect21.html。您应该能够在出版商提供的专门针对 XSLT 和 XPath 的各种书籍中找到对概念的深入解释。 cranesoftwrights.com/training/index.htm 也有在线资源,stackoverflow.com/tags/xslt/info 页面也有在线课程的链接。
    • 谢谢马丁!如果可能的话,您能否展示一下,我们如何使用轴名称(即,following-sibling::,preceding:: 等)实现相同的输出。
    猜你喜欢
    • 2012-11-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-30
    • 1970-01-01
    • 1970-01-01
    • 2019-07-02
    相关资源
    最近更新 更多