簡體   English   中英

使用 XSLT 轉換嵌套的 XML

[英]Transforming nested XML with XSLT

我似乎在使用 XSLT 方面取得了一些進展,但我仍然發現轉換嵌套 XML 非常困難。 XML 如下所示:

<transcription xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://www.livesandletters.ac.uk/schema/aor2_18112016.xsd">
    
    <page filename="00000005.tif" reader="Harvey" pagination="title page"/>
    <annotation>
        
        <marginalia hand="Italian">
            <language ident="LA">
                <position place="head" book_orientation="0">
                    <marginalia_text>gratum opus agricolis.</marginalia_text>
                </position>
            </language>
            <translation>The pleasant work for the husbandman.</translation>
        </marginalia>
        
    </annotation>
</transcription>

通過保留一些元素和屬性並修改其他元素和屬性,我想將其稍微轉換為:

<transcription xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://www.livesandletters.ac.uk/schema/aor2_18112016.xsd">
    
    <page filename="00000005.tif" reader="Harvey" pagination="title page"/>
    <annotation>
        
        <addition>
          <hand hands="Italian">
            <language ident="LA">
                <position place="head" book_orientation="0">
                    <note>gratum opus agricolis.</note>
                </position>
            </language>
            <translation>The pleasant work for the husbandman.</translation>
        </addition>
        
    </annotation>
</transcription>

到目前為止,我已經生成了這個 XSL,但由於某種原因,它不會復制 position 元素的屬性,也不會復制 marginia_text 元素(它成為轉換后的 XML 文件中的 note 元素)的內容。 知道我做錯了什么嗎? 我想過參考各種模板,但這也不起作用......

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8" indent="yes"/>
        <xsl:template match="@*|node()">
            <xsl:copy>
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:template>
        
    <xsl:template match="marginalia">
        <additions>
            <xsl:element name="hand">
                <xsl:attribute name="hands"><xsl:value-of select="@hand"/></xsl:attribute>
                <xsl:element name="position">
                    <xsl:attribute name="place"><xsl:value-of select="@place" /></xsl:attribute>
                    <xsl:attribute name="book_orientation"><xsl:value-of select="@book_orientation" /> 
                    </xsl:attribute>
                    <xsl:element name="note"><xsl:value-of select="marginalia_text"/>
                    </xsl:element>
                </xsl:element> 
            </xsl:element>
            <xsl:element name="translation"><xsl:value-of select="translation"/></xsl:element>
        </additions>
    </xsl:template>
</xsl:stylesheet>

您只是缺少指向所需屬性或元素的路徑。 請記住,您的模板與“邊緣”節點相匹配。 從那里您必須指定元素/屬性的路徑。

<xsl:stylesheet version="3.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8" indent="yes"/>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template>
        
    <xsl:template match="marginalia">
        <additions>
            <xsl:element name="hand">
                <xsl:attribute name="hands"><xsl:value-of select="@hand"/></xsl:attribute>
                <xsl:element name="position">
                    <xsl:attribute name="place"><xsl:value-of select="language/position/@place" /></xsl:attribute>
                    <xsl:attribute name="book_orientation"><xsl:value-of select="language/position/@book_orientation" /> 
                    </xsl:attribute>
                    <xsl:element name="note"><xsl:value-of select="language/position/marginalia_text"/>
                    </xsl:element>
                </xsl:element> 
            </xsl:element>
            <xsl:element name="translation"><xsl:value-of select="translation"/></xsl:element>
        </additions>
    </xsl:template>
</xsl:stylesheet>

看到它在這里工作: https : //xsltfiddle.liberty-development.net/nb9PtD1

您只需要使用所謂的身份轉換模式。 總體而言,您需要兩個專用模板來處理marginiamarginia_text元素。 其他所有內容都將按原樣從源 XML 文檔復制。

XSLT

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" encoding="utf-8" indent="yes"/>

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

    <xsl:template match="marginalia">
        <addition>
            <hand hands="{@hand}"/>
            <xsl:apply-templates/>
        </addition>
    </xsl:template>

    <xsl:template match="marginalia_text">
        <note>
            <xsl:value-of select="."/>
        </note>
    </xsl:template>
</xsl:stylesheet>

暫無
暫無

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

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