XSLT Nested Groups



我正在尝试创建一个 XSLT 来转换 XML 文档,但在形成嵌套组时遇到问题。下面是我的 xml

 <?xml version="1.0" encoding="UTF-8"?>
        <catalog>
           <mheader>
              <mid>1</mid>
              <mname>mn</mname>
           </mheader>
           <cheader>
              <cid>1</cid>
              <cname>cn</cname>
           </cheader>
           <lheader>
              <lid>1</lid>
              <lname>ln</lname>
           </lheader>
           <aheader>
              <aid>1</aid>
              <aname>an</aname>
           </aheader>
           <pos>
              <pid>1</pid>
              <pname>pay</pname>
           </pos>
           <pos>
              <pid>2</pid>
              <pname>pay1</pname>
           </pos>
    <lheader>
              <lid>1</lid>
              <lname>ln</lname>
           </lheader>
           <aheader>
              <aid>1</aid>
              <aname>an</aname>
           </aheader>
           <pos>
              <pid>1</pid>
              <pname>pay</pname>
           </pos>
           <pos>
              <pid>2</pid>
              <pname>pay1</pname>
           </pos>
           <mheader>
              <mid>2</mid>
              <mname>mh1</mname>
           </mheader>
           <cheader>
              <cid>2</cid>
              <cname>ch1</cname>
           </cheader>
           <lheader>
              <lid>2</lid>
              <lname>lh1</lname>
           </lheader>
           <aheader>
              <aid>2</aid>
              <aname>ah1</aname>
           </aheader>
           <pos>
              <pid>1</pid>
              <pname>pay</pname>
           </pos>
           <pos>
              <pid>2</pid>
              <pname>pay3</pname>
           </pos>
           <pos>
              <pid>3</pid>
              <pname>pay4</pname>
           </pos>
        </catalog>

我必须像下面这样转换我的 xml

        <?xml version="1.0" encoding="UTF-8"?>
    <catalog>
        <record>
            <mheader>
                <mid>1</mid>
                <mname>mn</mname>
            </mheader>
            <cheader>
                <cid>1</cid>
                <cname>cn</cname>
            </cheader>
            <location>
                <lheader>
                    <lid>1</lid>
                    <lname>ln</lname>
                </lheader>
                <aheader>
                    <aid>1</aid>
                    <aname>an</aname>
                </aheader>
                <pos>
                    <pid>1</pid>
                    <pname>pay</pname>
                </pos>
                <pos>
                    <pid>2</pid>
                    <pname>pay1</pname>
                </pos>
                </location>
                    <location>
                        <lheader>
                            <lid>1</lid>
                            <lname>ln</lname>
                        </lheader>
                        <aheader>
                            <aid>1</aid>
                            <aname>an</aname>
                        </aheader>
                        <pos>
                            <pid>1</pid>
                            <pname>pay</pname>
                        </pos>
                        <pos>
                            <pid>2</pid>
                            <pname>pay1</pname>
                        </pos>
                        </location>
        </record>
        <record>
            <mheader>
                <mid>2</mid>
                <mname>mh1</mname>
            </mheader>
            <cheader>
                <cid>2</cid>
                <cname>ch1</cname>
            </cheader>
<location>
            <lheader>
                <lid>2</lid>
                <lname>lh1</lname>
            </lheader>
            <aheader>
                <aid>2</aid>
                <aname>ah1</aname>
            </aheader>
            <pos>
                <pid>1</pid>
                <pname>pay</pname>
            </pos>
            <pos>
                <pid>2</pid>
                <pname>pay3</pname>
            </pos>
            <pos>
                <pid>3</pid>
                <pname>pay4</pname>
            </pos>
</location>
            <location>
                <lheader>
                    <lid>2</lid>
                    <lname>lh1</lname>
                </lheader>
                <aheader>
                    <aid>2</aid>
                    <aname>ah1</aname>
                </aheader>
                <pos>
                    <pid>1</pid>
                    <pname>pay</pname>
                </pos>
                <pos>
                    <pid>2</pid>
                    <pname>pay3</pname>
                </pos>
                <pos>
                    <pid>3</pid>
                    <pname>pay4</pname>
                </pos>
            </location>
        </record>
    </catalog>

这是我到目前为止使用 XSLT 的按组功能所做的

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="3.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:preserve-space elements="xsl:text"/>
    <xsl:strip-space elements="*"/>
    <xsl:output encoding="utf-8" method="xml" indent="yes"/>
 <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
    <xsl:template match="catalog">
        <xsl:copy>
            <xsl:for-each-group select="*" group-starting-with="mheader">
                <Record>
                    <xsl:for-each-group select="current-group()" group-starting-with="lheader">
                    <location>
                        <xsl:copy-of select="current-group()"/>
                    </location>
          </xsl:for-each-group>
                </Record>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

但是在转换后的 xml 中,mheader 和 cheader 标签被包装在位置标签中,如下所示

<location>
            <mheader>
                <mid>1</mid>
                <mname>mn</mname>
            </mheader>
            <cheader>
                <cid>1</cid>
                <cname>cn</cname>
            </cheader>
            </location>

谁能帮我创建正确的分组层次结构

提前谢谢。

如注释中所述,根据您的需要,将两个元素复制到内部for-each-group之前的输出中,然后将它们从内部分组中排除可能就足够了:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="3.0">
  <xsl:mode on-no-match="shallow-copy"/>
  <xsl:output method="xml" indent="yes"/>
  <xsl:strip-space elements="*"/>
    <xsl:template match="catalog">
        <xsl:copy>
            <xsl:for-each-group select="*" group-starting-with="mheader">
                <Record>
                    <xsl:copy-of select="current-group()[self::mheader | self::cheader]"/>
                    <xsl:for-each-group select="current-group()[not(self::mheader | self::cheader)]" group-starting-with="lheader">
                    <location>
                        <xsl:copy-of select="current-group()"/>
                    </location>
          </xsl:for-each-group>
                </Record>
            </xsl:for-each-group>
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

https://xsltfiddle.liberty-development.net/eiZQaFv 有一个在线样本。

相关内容

  • 没有找到相关文章

最新更新