应用模板无法正常工作

时间:2016-05-11 17:07:49

标签: xslt

给出以下xml输入: 文件1:

<?xml version="1.0" encoding="UTF-8"?>


<File1 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <code code="file1_code" displayName="file1_display" codeSystem="file1_cs" codeSystemName="file1_csn"/>

    <title>Title of file1</title>   
    <component typeCode="COMP">
        <structuredBody classCode="DOCBODY">
            <component typeCode="COMP">
                <section>
                    <templateId root="someRoot_file1" assigningAuthorityName="someAuhthority_file1"/>
                    <code code="file1-sec1_code" displayName="file1_sec1_display" codeSystem="file1_sec1_cs" codeSystemName="file1_sec1_csn"/>
                    <title>Tile of sec 1 from file1</title>
                    <text>
                        <content styleCode="Italics">
                            Text of sec 1 from file1
                        </content>
                    </text>             
                    <entry> file 1 sec 1                    
                    </entry>
                </section>
            </component>
            <component typeCode="COMP">
                <section classCode="DOCSECT">                   
                    <code code="file1_sec2_code" codeSystem="file2_sec2_cs" displayName="file2_sec2_display" codeSystemName="file2_sec2_csn"/>
                    <title>Tile from sec 2 file 1</title>
                    <text>
                        <content styleCode="Italics">
                            Text from file1 sec 2
                        </content>
                    </text>
                    <entry typeCode="test"> file2 sec 2
                    </entry>
                </section>
            </component>
        </structuredBody>
    </component>
</File1>

file2的:

<?xml version="1.0"?>
<A>
<title value="Title of file2"/>
    <text>
        <status value="generated"/>
        <div xmlns="http://www.w3.org/1999/xhtml">
            <p>File 2 Text</p>          
        </div>
    </text>
    <section>
        <code>
            <coding>
                <system value="sec 1 file2 sys"/>
                <code value="sec 1 file 2 code"/>
                <display value="sec 1 file 2 display"/>
            </coding>
        </code>
        <title>Title of sec 1 file2</title>
        <text>
            <content styleCode="Italics">Section 1 Text
            </content>
        </text>         
        <entry>
            <someEntry>                 
            </someEntry>
        </entry>
    </section>
    <section>
        <code>
            <coding>
                <system value="sec 2 file2 sys"/>
                <code value="sec 2 file 2 code"/>
                <display value="sec 2 file 2 display"/>
            </coding>
        </code>
        <title>Title of sec 2 file2</title>
        <text>
            <content styleCode="Italics">Section 2 file2 Text
            </content>
        </text>         
        <entry>
            <someEntry> entry sec 2 file 2              
            </someEntry>
        </entry>
    </section>

</A>

以及以下xslt:

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

        <xsl:strip-space elements="*" />

        <xsl:variable name="input" select="/" />

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

        <xsl:template match="/">
            <Bundle>
                <id value="test"/>          
                <type value="document"/>
                <entry>             
                    <resource>                  
                        <xsl:apply-templates select="document('file2.xml')/*"/>             
                    </resource> 
                </entry>
            </Bundle>
        </xsl:template>


        <xsl:template match="text">
            <text>
                <status value="generated"/>
                <div xmlns="http://www.w3.org/1999/xhtml">
                    <p>This is the text from the stylesheet </p>                
                </div>
            </text>
        </xsl:template>

        <xsl:template match="title">
            <xsl:apply-templates select="$input/File1/title"/>
        </xsl:template>

        <xsl:template match="section[1]">
            <xsl:apply-templates select="$input/File1/component/structuredBody/component/section"/>
        </xsl:template>

        <xsl:template match="section[2]"/>      

        <xsl:template match="File1/title">
            <title>
                <xsl:attribute name="value">
                    <xsl:value-of select="." />
                </xsl:attribute>
            </title>
        </xsl:template>

        <xsl:template match = "File1/component/structuredBody/component/section">       
            <section>
                <xsl:apply-templates/>
            </section>
        </xsl:template>


    </xsl:stylesheet>

这是输出:

<?xml version="1.0" encoding="UTF-8"?>
<Bundle>
    <id value="test"/>
    <type value="document"/>
    <entry>
        <resource>
            <A>
                <title value="Title of file1"/>
                <text>
                    <status value="generated"/>
                    <div xmlns="http://www.w3.org/1999/xhtml">
                        <p>This is the text from the stylesheet </p>
                    </div>
                </text>
                <section>
                    <templateId xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" root="someRoot_file1" assigningAuthorityName="someAuhthority_file1"/>
                    <code xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" code="file1-sec1_code" displayName="file1_sec1_display" codeSystem="file1_sec1_cs" codeSystemName="file1_sec1_csn"/>
                    <title value="Title of file1"/>
                    <text>
                        <status value="generated"/>
                        <div xmlns="http://www.w3.org/1999/xhtml">
                            <p>This is the text from the stylesheet </p>
                        </div>
                    </text>
                    <entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
                </section>
                <section>
                    <code xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" code="file1_sec2_code" codeSystem="file2_sec2_cs" displayName="file2_sec2_display" codeSystemName="file2_sec2_csn"/>
                    <title value="Title of file1"/>
                    <text>
                        <status value="generated"/>
                        <div xmlns="http://www.w3.org/1999/xhtml">
                            <p>This is the text from the stylesheet </p>
                        </div>
                    </text>
                    <entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" typeCode="test"/>
                </section>
            </A>
        </resource>
    </entry>
</Bundle>

这是预期的输出:

<?xml version="1.0" encoding="UTF-8"?>
<Bundle>
    <id value="test"/>
    <type value="document"/>
    <entry>
        <resource>
            <A>
                <title value="Title of file1"/>
                <text>
                    <status value="generated"/>
                    <div xmlns="http://www.w3.org/1999/xhtml">
                        <p>This is the text from the stylesheet </p>
                    </div>
                </text>             
                <section>
                    <templateId xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" root="someRoot_file1" assigningAuthorityName="someAuhthority_file1"/>
                    <code xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" code="file1-sec1_code" displayName="file1_sec1_display" codeSystem="file1_sec1_cs" codeSystemName="file1_sec1_csn"/>
                    <title>Tile of sec 1 from file1</title>
                    <text>
                        <content styleCode="Italics">
                            Text of sec 1 from file1
                        </content>
                    </text>             
                    <entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
                </section>
                <section>
                    <code xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" code="file1_sec2_code" codeSystem="file2_sec2_cs" displayName="file2_sec2_display" codeSystemName="file2_sec2_csn"/>
                    <title>Tile from sec 2 file 1</title>
                        <text>
                            <content styleCode="Italics">
                                Text from file1 sec 2
                            </content>
                        </text>
                    <entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" typeCode="test"/>
                </section>
            </A>
        </resource>
    </entry>
</Bundle>

我有以下问题:

  1. 当应用模板在File1/title范围内时,为什么部分元素中的标题来自主标题(即File1/component/structuredBody/component/section)?我期待该部分的标题将被输出,这是所期望的。更令人困惑的是它确实输出了像代码,条目等部分中的元素,但标题和文本(见下面的q2)似乎被区别对待,我不能理解为什么。

  2. 与文字相同。为什么段的文本没有输出?

  3. 这可能是对这个过程的错误理解:

    我们从<xsl:template match="/">开始并创建元素Bundle,id等,然后使用<xsl:apply-templates select="document('file2.xml')/*"/>我们匹配file2(A)的顶部元素,因为我们没有模板匹配明确地,调用身份模板,复制它并处理其子元素,即文本,标题和部分。对于每个子元素,它会查找匹配的模板。它找到它们并匹配它们。

    但是对于元素部分,由于<xsl:template match="section[1]">,它仅匹配第一个section元素,然后由于模板中的<xsl:apply-templates select="$input/File1/component/structuredBody/component/section"/>,它会查找与FIle1中的section的子节点匹配的模板,这是代码,文本,标题和templateId。它找不到这样明确定义的模板,因此为它们调用身份模板,复制并处理它们直到结束。至少这是我对它的理解。

2 个答案:

答案 0 :(得分:1)

  

为什么section元素中的标题来自主标题

因为只要指示处理器将模板应用于Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height, System.Drawing.Imaging.PixelFormat.Format32bppRgb); Graphics graphics = Graphics.FromImage(bitmap as Image); graphics.CopyFromScreen(bounds.Location, new Point(0, 0), bitmap.Size); ,它就会查找要应用的最佳匹配模板,并找到:

title

这会将上下文更改为File1.xml中的<xsl:template match="title"> <xsl:apply-templates select="$input/File1/title"/> </xsl:template> ,并且最适合此模板的模板是:

title

这就是你看到的结果。

  

与文字相同。为什么段的文本没有输出?

- 根据以下说明进行了编辑: -

  

当我说文字时,我只讨论文字元素。

原始的<xsl:template match="File1/title"> <title> <xsl:attribute name="value"> <xsl:value-of select="." /> </xsl:attribute> </title> </xsl:template> 元素(File1.xml中的text的子元素)未输出,因为您有一个特定的模板匹配它并输出其他内容:

section

答案 1 :(得分:0)

@ michael.hor257k和@Michael Kay耶,这绝对是这样,我误解了xsl:apply-templates关于语境的方式。我想是因为我在xsl:apply-templates内调用了xsl:template match = "$input/File1/component/structuredBody/component/section">,它只会查找与section的子节点匹配的匹配模板。换句话说,我认为它会寻找像“<xsl:template match=”File1/component/structuredBody/component/section/title">这样的模板,但事实显然并非如此。

xsl:apply-templates只是查找子项,然后查找匹配模板,而不管它们被调用的上下文。因此,它会查找匹配的标题或文本模板,如果找到它们,它将匹配它们。

我能找到的解决问题的最简单的解决方案是添加标题和文本模板的路径。换句话说,我应该<xsl:template match="text">而不仅仅是<xsl:template match="A/text">。标题相同。这样,xsl:apply-templates将不会应用<xsl:template match="A/text">,因为节中的标题不是A的子节点。因此,如果未定义匹配的显式模板,则将应用标识模板并输出标题根据需要的部分。