簡體   English   中英

使用 XSLT1.0 將平面 XML 數據轉換為嵌套的 XML

[英]Convert flat XML data into nested XML using XSLT1.0

我有一個分組問題,我需要將節點下具有相同編號的所有鍵分組。 例如,我的 XML 看起來像:

<results>
   <status>completed</status>
   <info>success</info>
   <prod1>abc</prod1>
   <pub1>test</pub1>
   <sub1>123</sub1>
   <subtype1>pt</subtype1>
   <prod2>def</prod2>
   <pub2>test22</pub2>
   <sub2>456</sub2>
   <subtype2>pt</subtype2>
   <prod3>ghi</prod3>
   <pub3>test33</pub3>
   <sub3>789</sub3>
   <subtype3>pt</subtype3>
</results>

我需要將上述內容轉換為:

<results>
   <status>completed</status>
   <info>success</info>
   <products>
      <product>
         <prod>abc</prod>
         <pub>test</pub>
         <sub>123</sub>
         <subtype>pt</subtype>
       </product>
       <product>
         <prod>def</prod>
         <pub>test22</pub>
         <sub>456</sub>
         <subtype>pt</subtype>
       </product>
       <product>
         <prod>ghi</prod>
         <pub>test33</pub>
         <sub>789</sub>
         <subtype>pt</subtype>
       </product>
    </products>
</results>

對解決上述問題的任何幫助表示高度贊賞。 我目前被這個問題困住了,無法繼續。

下面的 xslt 拉出每個元素並放入一個節點中,我無法將所有以特定數字結尾的元素分組到一個節點中。

<?xml version="1.0" encoding="UTF-8"?>
   <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
   <xsl:key name="elementByRow" match="/*/*"
           use="(name(.)[1])" />

   <xsl:template match="/messages">
    <messages>
      <!-- pick out the first RowN.* element for each N -->
      <xsl:apply-templates select="*[generate-id() =
         generate-id(key('elementByRow', name(.))[1])]" />
    </messages>
   </xsl:template>

   <xsl:template match="*">
    <row>
      <!-- process _all_ the elements that belong to this row -->
      <xsl:for-each select="key('elementByRow', name(.))[1]">
        <xsl:element name="{name(.)[1]}">
          <xsl:value-of select="." />
        </xsl:element>
      </xsl:for-each>
     </row>
    </xsl:template>
   </xsl:stylesheet>

如果輸入結構是恆定的,我會利用它,而不是嘗試按尾隨數字分組。

例如,你可以這樣做:

XSLT 1.0

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

<xsl:template match="/results">
    <xsl:copy>
        <xsl:copy-of select="status | info"/>
        <products>
            <xsl:for-each select="*[starts-with(name(), 'prod')]">
                <product>
                    <prod>
                        <xsl:value-of select="." />
                    </prod>
                    <pub>
                        <xsl:value-of select="following-sibling::*[1]" />
                    </pub>
                    <sub>
                        <xsl:value-of select="following-sibling::*[2]" />
                    </sub>
                    <subtype>
                        <xsl:value-of select="following-sibling::*[3]" />
                    </subtype>
                </product>
            </xsl:for-each>
        </products>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

這是一種更精細的方法,它按元素的數量對元素進行分組; 但是請注意,這假定元素的名稱將不包含末尾組編號以外的任何數字。

XSLT 1.0

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

<xsl:key name="field-by-group" match="*" use="translate(name(), translate(name(), '0123456789', ''), '')" />

<xsl:template match="/results">
    <xsl:copy>
        <xsl:copy-of select="status | info"/>
        <products>
            <xsl:for-each select="*[starts-with(name(), 'prod')]">
                <product>
                    <xsl:for-each select="key('field-by-group', substring-after(name(), 'prod'))">
                        <xsl:element name="{translate(name(), '0123456789', '')}">
                            <xsl:value-of select="."/>
                        </xsl:element>
                    </xsl:for-each>
                </product>
            </xsl:for-each>
        </products>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM