【问题标题】:Transform XML with XSL使用 XSL 转换 XML
【发布时间】:2026-02-22 00:55:02
【问题描述】:

所以我已经到了我自己似乎无法解决问题的地步。 我必须转换这个 XML 代码:

<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="xml.xsl"?>
<ansokan>
    <forskolaNamn>FakeFörskola</forskolaNamn>

    <barn personnummer="1234567890">
        <namn>Abc</namn>
        <allergi>Räkor</allergi>
        <övrigt> </övrigt>
    </barn>

    <syskon personnummer="1678901234">
        <namn>ABCs Bror</namn>
    </syskon>

    <vardnadshavare personnummer="1456789012">
        <fornamn>ABCs</fornamn>
        <efternamn>Vårdnadsavare1</efternamn>
        <adress>Fake Street</adress>
        <telefon hem="031111111" mobil="0731234567"/>
        <e-post>Vårdnadsavare1@gmail.com</e-post>
    </vardnadshavare>

    <vardnadshavare personnummer="1789012345">
        <fornamn>ABCs</fornamn>
        <efternamn>Vårdnadsavare2</efternamn>
        <adress>FakeFake Street</adress>
        <telefon hem="031333333" />
        <e-post>Vårdnadsavare2@gmail.com</e-post>
    </vardnadshavare>
</ansokan>

所有这些元素和属性应该只输出元素“vardnadshavare”中的属性“Personnumer”和元素fornamn晚上。像这样:

<begaranominkomstuppgift>       
    <person personnummer="1456789012">       
        <fornamn>ABCs</fornamn>        
        <efternamn>Vårdnadsavare1</efternamn>       
    </person>       
    <person personnummer="1789012345">        
        <fornamn>ABCs</fornamn>        
        <efternamn>Vårdnadsavare2</efternamn>      
    </person>    
</begaranominkomstuppgift>

这是我的 XSL 代码:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="ansokningar">
        <begaranominkomstuppgift>
            <xsl:for-each select="ansokan/vardnadshavare">
                <person>
                    <xsl:attribute name="personnummer">
                        <xsl:value-of select="@personnummer"/>
                    </xsl:attribute>
                    <fornamn>
                        <xsl:value-of select="fornamn"/>
                    </fornamn>
                    <efternamn>
                        <xsl:value-of select="efternamn"/>
                    </efternamn>
                </person>
            </xsl:for-each>
        </begaranominkomstuppgift>
    </xsl:template>
</xsl:stylesheet>

当我测试代码时没有任何结果。顺便说一句,XML 代码已经过验证。

【问题讨论】:

  • 你的根元素是ansokan,而你的模板匹配ansokningar

标签: xml xslt


【解决方案1】:

正如@Filburt 所写,您匹配了错误的根元素。

你修改后的 xsl:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="yes"/>
    <xsl:template match="ansokan">
        <begaranominkomstuppgift>
            <xsl:for-each select="vardnadshavare">
                <person>
                    <xsl:attribute name="personnummer">
                        <xsl:value-of select="@personnummer"/>
                    </xsl:attribute>
                    <fornamn>
                       <xsl:value-of select="fornamn"/>
                    </fornamn>
                    <efternamn>
                       <xsl:value-of select="efternamn"/>
                    </efternamn>
                 </person>
            </xsl:for-each>
        </begaranominkomstuppgift>
    </xsl:template>
</xsl:stylesheet>

【讨论】:

    【解决方案2】:

    我想添加一个稍微不同的方法,因为我更喜欢模板而不是 for-each

    <?xml version="1.0" encoding="utf-8"?>
    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <xsl:output method="xml" indent="yes"/>
    
        <!-- start out with document root template -->
        <xsl:template match="/">
            <xsl:apply-templates />
        </xsl:template>
    
        <!-- match new root element -->
        <xsl:template match="ansokan">
            <xsl:element name="begaranominkomstuppgift">
                <xsl:apply-templates />
            </xsl:element>
        </xsl:template>
    
        <!-- match new person element -->
        <xsl:template match="vardnadshavare">
            <xsl:element name="person">
                <xsl:attribute name="personnummer">
                    <xsl:value-of select="./@personnummer" />
                </xsl:attribute>
                <xsl:apply-templates />
            </xsl:element>
        </xsl:template>
    
        <!-- empty templates for those elements to ignore -->
        <xsl:template match="forskolaNamn" />
        <xsl:template match="barn" />
        <xsl:template match="syskon" />
        <xsl:template match="adress" />
        <xsl:template match="telefon" />
        <xsl:template match="e-post" />
    
        <!-- identity template for copying those elements that need no transformation -->
        <xsl:template match="@* | node()">
            <xsl:copy>
                <xsl:apply-templates select="@* | node()"/>
            </xsl:copy>
        </xsl:template>
    </xsl:stylesheet>
    

    【讨论】:

    • 它可能看起来有点复杂,并且超出了您手头任务的需要,但它可能会让您对即将完成的更大任务有所了解。
    • 是的,我不能说我理解它的每一个部分,但它似乎并没有那么糟糕。我必须制作的 XSD 对我来说读/写有点困难。