谁能解释下面的 xsl 是如何工作的?

Posted

技术标签:

【中文标题】谁能解释下面的 xsl 是如何工作的?【英文标题】:Can anyone explain how does the below xsl works? 【发布时间】:2021-09-27 01:14:31 【问题描述】:

谁能用一个例子解释一下下面的 xsl 是如何工作的?


    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
        <!--  Remove empty elements or attributes -->
        <xsl:template match="@*|node()">
            <xsl:if test=". != '' or ./@* != ''">
                <xsl:copy>
                    <xsl:apply-templates select="@*|node()"/>
                </xsl:copy>
            </xsl:if>
        </xsl:template>
    </xsl:stylesheet>

当我将上面的 xsl 用于下面的未缩进的 xml 时(注意它在下面显示缩进但认为它没有缩进。输入文本框不允许我放置未缩进的 xml):


<Book Edition="1234" Type="Novel" TimeStamp="2021-07-09T14:02:55-05:00" Version="1.003">
    <BOS>
        <LIB>
            <RequestorID ID="XXX" Type="10"/>
        </LIB>
    </BOS>
    <Sections>
        <Section CreateDateTime="2021-07-03T11:21:43-05:00" CreatorID="XXX" Status="Read">
            <UniqueID ID="443791" Type="10"/>
            <Chapters>
                <Chapter>
                    <Paragraphs>
                        <Paragraph NumberOfUnits="10" Lines="100">
                            <Rates>
                                <Rate EffectiveDate="2021-12-12" ExpireDate="2021-12-13" RateTimeUnit="Day" UnitMultiplier="1">
                                    <Base AmountBeforeTax="145.90" CurrencyCode="USD"/>
                                </Rate>
                            </Rates>
                        </Paragraph>
                    </Paragraphs>
                    <Readers>
                        <Reader Age="10" Count="1"/>
                    </Readers>
                    <TimeSpan End="2021-12-13" Start="2021-12-12"/>
                    <BasicInfo BookCode="1310"/>
                </Chapter>
            </Chapters>
            <Authors>
                <Author AuthorRPH="1">
                    <Profiles>
                        <ProfileInfo>
                            <UniqueID ID="44379" Type="1"/>
                            <Profile ProfileType="1">
                                <Author>
                                    <PersonName>
                                        <GivenName>TEST</GivenName>
                                        <Surname>TEST</Surname>
                                    </PersonName>
                                    <Telephone PhoneNumber="0"/>
                                    <Email>test@test.com</Email>
                                    <Address Type="H">
                                        <AddressLine>123 MAIN ST</AddressLine>
                                    </Address>
                                </Author>
                            </Profile>
                        </ProfileInfo>
                    </Profiles>
                </Author>
            </Authors>
            <GlobalInfo>
                <ReadIds>
                    <ReadId ReadID_Source="ZZZ" ReadID_Type="10" ReadID_Value="1234"/>
                </ReadIds>
            </GlobalInfo>
        </Section>
    </Sections>
</Book>

然后我得到以下输出:


         <Book Edition="1234" Type="Novel" TimeStamp="2021-07-09T14:02:55-05:00" Version="1.003">
                <BOS>
                    <LIB>
                        <RequestorID ID="XXX" Type="10"/>
                    </LIB>
                </BOS>
                <Sections>
                    <Section CreateDateTime="2021-07-03T11:21:43-05:00" CreatorID="XXX" Status="Read">
                        <UniqueID ID="443791" Type="10"/>
                        <Authors>
                            <Author AuthorRPH="1">
                                <Profiles>
                                    <ProfileInfo>
                                        <UniqueID ID="44379" Type="1"/>
                                        <Profile ProfileType="1">
                                            <Author>
                                                <PersonName>
                                                    <GivenName>TEST</GivenName>
                                                    <Surname>TEST</Surname>
                                                </PersonName>
                                                <Telephone PhoneNumber="0"/>
                                                <Email>test@test.com</Email>
                                                <Address Type="H">
                                                    <AddressLine>123 MAIN ST</AddressLine>
                                                </Address>
                                            </Author>
                                        </Profile>
                                    </ProfileInfo>
                                </Profiles>
                            </Author>
                        </Authors>
                    </Section>
                </Sections>
            </Book>

如上所示,它会删除章节标签和全局信息标签内的所有内容

但是如果我使用上面的 xsl 用于下面的缩进的 xml:


        <Book Edition="1234" Type="Novel" TimeStamp="2021-07-09T14:02:55-05:00" Version="1.003">
            <POS>
                <Source>
                    <RequestorID ID="XXX" Type="10"/>
                </Source>
            </POS>
            <Sections>
                <Section CreateDateTime="2021-07-03T11:21:43-05:00" CreatorID="XXX" Status="Read">
                    <UniqueID ID="443791" Type="10"/>
                    <Chapters>
                        <Chapter>
                            <Paragraphs>
                                <Paragraph NumberOfUnits="10" Lines="100">
                                    <Rates>
                                        <Rate EffectiveDate="2021-12-12" ExpireDate="2021-12-13" RateTimeUnit="Day" UnitMultiplier="1">
                                            <Base AmountBeforeTax="145.90" CurrencyCode="USD"/>
                                        </Rate>
                                    </Rates>
                                </Paragraph>
                            </Paragraphs>
                            <Readers>
                                <Reader Age="10" Count="1"/>
                            </Readers>
                            <TimeSpan End="2021-12-13" Start="2021-12-12"/>
                        
                            <BasicInfo BookCode="1310"/>
                        </Chapter>
                    </Chapters>
                    <Authors>
                        <Author AuthorRPH="1">
                            <Profiles>
                                <ProfileInfo>
                                    <UniqueID ID="44379" Type="1"/>
                                    <Profile ProfileType="1">
                                        <Author>
                                            <PersonName>
                                                <GivenName>TEST</GivenName>
                                                <Surname>TEST</Surname>
                                            </PersonName>
                                            <Telephone PhoneNumber="0"/>
                                            <Email>test@test.com</Email>
                                            <Address Type="H">
                                                <AddressLine>123 MAIN ST</AddressLine>
                                            </Address>
                                        </Author>
                                    </Profile>
                                </ProfileInfo>
                            </Profiles>
                        </Author>
                    </Authors>
                    <GlobalInfo>
                        <ReadIds>
                            <ReadId ReadID_Source="ZZZ" ReadID_Type="10" ReadID_Value="1234"/>
                        </ReadIds>
                    </GlobalInfo>
                </Section>
            </Sections>
        </Book>

然后我得到正确的输出:

 

       <Book Edition="1234" Type="Novel" TimeStamp="2021-07-09T14:02:55-05:00" Version="1.003">
            <BOS>
                <LIB>
                    <RequestorID ID="XXX" Type="10"/>
                </LIB>
            </BOS>
            <Sections>
                <Section CreateDateTime="2021-07-03T11:21:43-05:00" CreatorID="XXX" Status="Read">
                    <UniqueID ID="443791" Type="10"/>
                    <Chapters>
                        <Chapter>
                            <Paragraphs>
                                <Paragraph NumberOfUnits="10" Lines="100">
                                    <Rates>
                                        <Rate EffectiveDate="2021-12-12" ExpireDate="2021-12-13" RateTimeUnit="Day" UnitMultiplier="1">
                                            <Base AmountBeforeTax="145.90" CurrencyCode="USD"/>
                                        </Rate>
                                    </Rates>
                                </Paragraph>
                            </Paragraphs>
                            <Readers>
                                <Reader Age="10" Count="1"/>
                            </Readers>
                            <TimeSpan End="2021-12-13" Start="2021-12-12"/>
                            <BasicInfo BookCode="1310"/>
                        </Chapter>
                    </Chapters>
                    <Authors>
                        <Author AuthorRPH="1">
                            <Profiles>
                                <ProfileInfo>
                                    <UniqueID ID="44379" Type="1"/>
                                    <Profile ProfileType="1">
                                        <Author>
                                            <PersonName>
                                                <GivenName>TEST</GivenName>
                                                <Surname>TEST</Surname>
                                            </PersonName>
                                            <Telephone PhoneNumber="0"/>
                                            <Email>test@test.com</Email>
                                            <Address Type="H">
                                                <AddressLine>123 MAIN ST</AddressLine>
                                            </Address>
                                        </Author>
                                    </Profile>
                                </ProfileInfo>
                            </Profiles>
                        </Author>
                    </Authors>
                    <GlobalInfo>
                        <ReadIds>
                            <ReadId ReadID_Source="ZZZ" ReadID_Type="10" 
    ReadID_Value="1234"/>
                        </ReadIds>
                    </GlobalInfo>
                </Section>
            </Sections>
        </Book>

谁能解释一下xmls是否相同,为什么缩进会给出不同的输出?适当的缩进会影响 xsl 转换吗?

【问题讨论】:

它执行identity transform 并为空元素添加了过滤器。 【参考方案1】:

测试中的 XPath 表达式 . != '' or ./@* != '' 的行为可能与您预期的不同。 XPath 1.0 的规范(通常与 XSLT 1.0 一起使用),如 version="1.0" 所示,https://www.w3.org/TR/1999/REC-xpath-19991116/#dt-string-value

对于每种类型的节点,都有一种确定字符串值的方法 对于该类型的节点。对于某些类型的节点,字符串值是 节点的一部分;对于其他类型的节点,字符串值为 根据后代节点的字符串值计算。

在“5.2 元素节点”一节中

元素节点的字符串值是 元素节点的所有文本节点后代的字符串值 按文档顺序。

因此,对于普通的非缩进源元素,字符串转换涉及递归下降到元素并获取它们的值(忽略属性)。在您的情况下,对于一个也没有属性的元素,如果它没有任何像 &lt;elem&gt;value&lt;/elem&gt; 这样的值的元素,则整个子树将被消除(即不复制到输出)。

使用缩进源,您还有代表节点之间空白的节点。 (XPath 不知道空格与您无关,并假定混合内容。)这会导致具有(缩进)子元素的元素的字符串转换在字符串的结果中(至少)具有该空格转换,使. != '' XPath 表达式为 false。

我希望,这可以解释结果的差异取决于源代码中的缩进。

您可能想查看https://www.w3.org/TR/1999/REC-xpath-19991116/#function-normalize-space 以调整转换结果。请注意,如果这些都可以是空白,这也可能会影响对“真实值”的尊重。

编辑:根据您想要实现的目标,您可能会考虑使用 xsl:strip-space 让 XSLT 处理器消除空白。

【讨论】:

两个标签之间的空格是否被视为文本节点?或者,如果每个标签都在新行上,如下所示,那么新行是否被视为文本节点? 或 是的,两个标签之间的空白被映射到一个文本节点。它包含所有字符,即不仅包含换行符,还包含制表符和空格。如果您使用xsl:strip-whitespace,这些文本节点将在处理之前被消除。【参考方案2】:

代码有一个匹配所有元素、文本、注释、处理指令和属性节点的模板规则。如果节点具有非空字符串值,或者具有非空字符串值的属性,则它会浅拷贝节点并递归处理其属性和子节点。

总体效果是复制整个文档,除了没有内容且没有非空属性的元素(例如&lt;br/&gt;)- 加上一些其他例外,例如空 cmets。

【讨论】:

以上是关于谁能解释下面的 xsl 是如何工作的?的主要内容,如果未能解决你的问题,请参考以下文章

谁能解释一下这个java代码是如何工作的?

谁能解释这段代码是如何工作的?

谁能给我一个xsl中模板“模式”的例子吗?

有人可以解释这段代码如何返回 4

谁能解释如何执行视觉工作室程序? [关闭]

谁能解释一下这个python代码中提到的一行的工作原理?