【问题标题】:Presenting elements in the order they appear in XML按元素在 XML 中出现的顺序呈现元素
【发布时间】:2018-05-26 10:31:26
【问题描述】:

总的来说,我在 XSLT 和 XML 方面相对较新。 我正在尝试能够转换具有如下部分的 XML 文件:

        <messageTypes>
        <id>EOL</id>
        <Headline>this is the headline of a message
        </Headline>
        <Description>1. This is the description of a message</Description>
        <infoTable>
            <fieldName>EOL</fieldName>
            <DTLink>
                <DTLinkL>string(3)</DTLinkL>
                <DTLinkT>string(3)</DTLinkT>
            </DTLink>
            <fieldSize>1</fieldSize>
            <fieldValue>0x42</fieldValue>
            <descriptionWithLink>
                <Description>it's the end of the world as we know it</Description>
                <XLink>
                    <XLinkL>https://stackoverflow.com/questions/13780145/inserting-images-from-xml-to-xsl-document
                    </XLinkL>
                    <XLinkT>here's a link for ye</XLinkT>
                </XLink>
                <SLink>
                    <SLinkL>header</SLinkL>
                    <SLinkT>This is also like this type of structure header</SLinkT>
                </SLink>
            </descriptionWithLink>
        </infoTable>
        <optionalElement id="Choice 1">
            <fieldName>option A</fieldName>
            <DTLink>
                <DTLinkL>string(4)</DTLinkL>
                <DTLinkT>string(4)</DTLinkT>
            </DTLink>
            <fieldSize>1</fieldSize>
            <fieldValue>0xdeadbeef</fieldValue>
            <descriptionWithLink>
                <Description>dead beef is dead beef</Description>
                <XLink>
                    <XLinkL>https://stackoverflow.com/questions/13780145/inserting-images-from-xml-to-xsl-document
                    </XLinkL>
                    <XLinkT>here's a link for ye</XLinkT>
                </XLink>
            </descriptionWithLink>
        </optionalElement>
        <infoTable>
            <fieldName>EOL</fieldName>
            <DTLink>
                <DTLinkL>string(2)</DTLinkL>
                <DTLinkT>string(2)</DTLinkT>
            </DTLink>
            <fieldSize>1</fieldSize>
            <fieldValue>0x42</fieldValue>
            <descriptionWithLink>
                <Description>it's the end of the world as we know it</Description>
                <XLink>
                    <XLinkL>https://stackoverflow.com/questions/13780145/inserting-images-from-xml-to-xsl-document
                    </XLinkL>
                    <XLinkT>here's a link for ye</XLinkT>
                </XLink>
                <SLink>
                    <SLinkL>middle</SLinkL>
                    <SLinkT>This is also like this type of structure middle</SLinkT>
                </SLink>
            </descriptionWithLink>
        </infoTable>

对于能够表达这一点的东西:

表格部分的“如果”分解,以便 1. 您可以在这里拥有一个元素(这将导致更常见的消息类型)或另一个元素(这将导致不同但更罕见的元素类型)。 2. 请注意,OptionalElement 中详述的可能部分并不常见,但可能会发生。

我构建的 XSL 如下所示:

<h1>Messages</h1>
                <xsl:for-each
                    select="m:SectionMessageTypes/m:messageTypes">
                    <xsl:variable name="MessageID" select="m:id" />
                    <h3 id="{$MessageID}">
                        <xsl:value-of select="m:Headline" />
                    </h3>
                    <p>
                        <xsl:value-of select="m:Description" />
                    </p>
                    <table width="80%" border="2" cellpadding="5">
                        <tr bgcolor="#87CEFA">
                            <td>Name</td>
                            <td>Type</td>
                            <td>Size</td>
                            <td>Value</td>
                            <td>Description</td>
                        </tr>
                        <xsl:for-each select="m:infoTable">
                            <xsl:variable name="MessageID" select="m:id" />
                            <tr>
                                <xsl:choose>
                                    <xsl:when test="m:fieldName='header'">
                                        <td>
                                            <a href="#header">Header</a>
                                        </td>
                                    </xsl:when>
                                    <xsl:otherwise>
                                        <td>
                                            <xsl:value-of select="m:fieldName" />
                                        </td>
                                    </xsl:otherwise>
                                </xsl:choose>
                                <td>
                                    <xsl:variable name="DTLinkV"
                                        select="m:DTLink/m:DTLinkL" />
                                    <a href="#{$DTLinkV}">
                                        <xsl:value-of select="m:DTLink/m:DTLinkT" />
                                    </a>
                                </td>
                                <td>
                                    <xsl:value-of select="m:fieldSize" />
                                </td>
                                <td>
                                    <xsl:value-of select="m:fieldValue" />
                                </td>
                                <td>
                                    <xsl:value-of
                                        select="m:descriptionWithLink/m:Description" />
                                    <br />
                                    <xsl:if test="m:descriptionWithLink/m:XLink">
                                        <xsl:variable name="XLinkV"
                                            select="m:descriptionWithLink/m:XLink/m:XLinkL" />
                                        <a href="{$XLinkV}">
                                            <xsl:value-of
                                                select="m:descriptionWithLink/m:XLink/m:XLinkT" />
                                        </a>
                                        <br />
                                    </xsl:if>
                                    <xsl:if test="m:descriptionWithLink/m:DLink">
                                        <xsl:variable name="DLinkV"
                                            select="m:descriptionWithLink/m:DLink/m:DLinkL" />
                                        <a href="#{$DLinkV}">
                                            <xsl:value-of
                                                select="m:descriptionWithLink/m:DLink/m:DLinkT" />
                                        </a>
                                        <br />
                                    </xsl:if>
                                    <xsl:if test="m:descriptionWithLink/m:MLink">
                                        <xsl:variable name="MLinkV"
                                            select="m:descriptionWithLink/m:MLink/m:MLinkL" />
                                        <a href="#{$MLinkV}">
                                            <xsl:value-of
                                                select="m:descriptionWithLink/m:MLink/m:MLinkT" />
                                        </a>
                                        <br />
                                    </xsl:if>
                                    <xsl:if test="m:descriptionWithLink/m:DTLink">
                                        <xsl:variable name="DTLinkV"
                                            select="m:descriptionWithLink/m:DTLink/m:DTLinkL" />
                                        <a href="#{$DTLinkV}">
                                            <xsl:value-of
                                                select="m:descriptionWithLink/m:DTLink/m:DTLinkT" />
                                        </a>
                                        <br />
                                    </xsl:if>
                                    <xsl:if test="m:descriptionWithLink/m:SLink">
                                        <xsl:variable name="SLinkV"
                                            select="m:descriptionWithLink/m:SLink/m:SLinkL" />
                                        <a href="#{$SLinkV}">
                                            <xsl:value-of
                                                select="m:descriptionWithLink/m:SLink/m:SLinkT" />
                                        </a>
                                        <br />
                                    </xsl:if>
                                </td>
                            </tr>
                        </xsl:for-each>
                    </table>
                    <table width="80%" border="2" cellpadding="5">
                        <tr bgcolor="#E0FFFF">
                            <td>Name</td>
                            <td>Type</td>
                            <td>Size</td>
                            <td>Value</td>
                            <td>Description</td>
                        </tr>
                        <xsl:for-each select="m:optionalElement">
                            <tr>
                                <img src="./Flowchart_condition_symbol.svg.png" width="42"
                                    height="42" />
                                <xsl:value-of select="@id" />
                            </tr>
                            <tr>
                                <xsl:choose>
                                    <xsl:when test="m:fieldName='header'">
                                        <td>
                                            <a href="#header">Header</a>
                                        </td>
                                    </xsl:when>
                                    <xsl:otherwise>
                                        <td>
                                            <xsl:value-of select="m:fieldName" />
                                        </td>
                                    </xsl:otherwise>
                                </xsl:choose>
                                <td>
                                    <xsl:variable name="DTLinkV"
                                        select="m:DTLink/m:DTLinkL" />
                                    <a href="#{$DTLinkV}">
                                        <xsl:value-of select="m:DTLink/m:DTLinkT" />
                                    </a>
                                </td>
                                <td>
                                    <xsl:value-of select="m:fieldSize" />
                                </td>
                                <td>
                                    <xsl:value-of select="m:fieldValue" />
                                </td>
                                <td>
                                    <xsl:value-of
                                        select="m:descriptionWithLink/m:Description" />
                                    <br />
                                    <xsl:if test="m:descriptionWithLink/m:XLink">
                                        <xsl:variable name="XLinkV"
                                            select="m:descriptionWithLink/m:XLink/m:XLinkL" />
                                        <a href="{$XLinkV}">
                                            <xsl:value-of
                                                select="m:descriptionWithLink/m:XLink/m:XLinkT" />
                                        </a>
                                        <br />
                                    </xsl:if>
                                    <xsl:if test="m:descriptionWithLink/m:DLink">
                                        <xsl:variable name="DLinkV"
                                            select="m:descriptionWithLink/m:DLink/m:DLinkL" />
                                        <a href="#{$DLinkV}">
                                            <xsl:value-of
                                                select="m:descriptionWithLink/m:DLink/m:DLinkT" />
                                        </a>
                                        <br />
                                    </xsl:if>
                                    <xsl:if test="m:descriptionWithLink/m:MLink">
                                        <xsl:variable name="MLinkV"
                                            select="m:descriptionWithLink/m:MLink/m:MLinkL" />
                                        <a href="#{$MLinkV}">
                                            <xsl:value-of
                                                select="m:descriptionWithLink/m:MLink/m:MLinkT" />
                                        </a>
                                        <br />
                                    </xsl:if>
                                    <xsl:if test="m:descriptionWithLink/m:DTLink">
                                        <xsl:variable name="DTLinkV"
                                            select="m:descriptionWithLink/m:DTLink/m:DTLinkL" />
                                        <a href="#{$DTLinkV}">
                                            <xsl:value-of
                                                select="m:descriptionWithLink/m:DTLink/m:DTLinkT" />
                                        </a>
                                        <br />
                                    </xsl:if>
                                    <xsl:if test="m:descriptionWithLink/m:SLink">
                                        <xsl:variable name="SLinkV"
                                            select="m:descriptionWithLink/m:SLink/m:SLinkL" />
                                        <a href="#{$SLinkV}">
                                            <xsl:value-of
                                                select="m:descriptionWithLink/m:SLink/m:SLinkT" />
                                        </a>
                                        <br />
                                    </xsl:if>
                                </td>
                            </tr>
                        </xsl:for-each>
                    </table>

这使得 HTML 页面看起来像这样:

如您所见....OptionalElement 不会出现在两个 InfoTable 元素之间。

有没有非css的方式来做到这一点?

这是一个工作项目,恐怕我还没有时间进入 CSS 领域。

【问题讨论】:

    标签: html xml xslt-1.0


    【解决方案1】:

    将内部 for-each 循环更改为

    <xsl:for-each select="m:infoTable | m:optionalElement">
    

    然后m:optionalElement 将在两个m:infoTable 元素之间处理 - 按文档顺序。

    在循环中,如果处理不同(确实如此),则必须区分这两者。例如与

    <xsl:choose>
        <xsl:when test="self::m:infoTable">
            ...
        </xsl:when>
        <xsl:when test="self::m:optionalElement">
            <h1>OPTION</h1>
        </xsl:when>
    </xsl:choose>
    

    【讨论】:

    • 没关系,我想通了
    • 如果我的回答有帮助,一般都会接受 ;-)
    • 不知道是不是,我没试过,我试过了。我所做的工作。不是说你的可能行不通,只是我无法验证。
    • 如果您自己找到了解决方案,没关系。祝您继续努力。
    【解决方案2】:

    我想通了!

    首先,在 XSD 中将 optionalElement 添加到您的 infoTable 和另一个名为 rowType 的新元素:

        <xs:element name="infoTable">
        <xs:complexType>
            <xs:all>
                <xs:element name="id" type="xs:string" minOccurs="0" />
                <xs:element name="fieldName" type="xs:string"
                    minOccurs="0" />
                <xs:element name="fieldType" type="xs:string"
                    minOccurs="0" />
                <xs:element ref="DTLink" minOccurs="0" />
                <xs:element name="fieldSize" type="xs:string"
                    minOccurs="0" />
                <xs:element name="fieldValue" type="xs:string"
                    minOccurs="0" />
                <xs:element ref="descriptionWithLink" minOccurs="0" />
                <xs:element name="rowType" minOccurs="0" />
                <xs:element name="optionalElement" minOccurs="0"/>
                <xs:element ref="Example" minOccurs="0" />
            </xs:all>
        </xs:complexType>
    </xs:element>
    

    然后,像这样创建每个 infoTable 元素:

                <infoTable>
                <rowType>else</rowType>
                <optionalElement>
                    CLIENT_SECURE_CONNECTION is not set in either
                    server-caps or client-caps
                </optionalElement>
                <fieldName>Password</fieldName>
                <DTLink>
                    <DTLinkL>NullTerminatedString</DTLinkL>
                    <DTLinkT>NullTerminatedString</DTLinkT>
                </DTLink>
                <fieldValue>varies</fieldValue>
                <descriptionWithLink>
                    <Description>Plain text password. Used by older clients and
                        servers
                    </Description>
                </descriptionWithLink>
            </infoTable>
            <infoTable>
                <rowType>data</rowType>
                <fieldName>DB Name</fieldName>
                <DTLink>
                    <DTLinkL>NullTerminatedString</DTLinkL>
                    <DTLinkT>NullTerminatedString</DTLinkT>
                </DTLink>
                <fieldSize>Length </fieldSize>
                <fieldValue>.</fieldValue>
                <descriptionWithLink>
                    <Description>The database name to connect to. DB Name should be
                        taken from this field. Value is UTF-8 encoded.
                    </Description>
                </descriptionWithLink>
            </infoTable>
            <infoTable>
            <rowType>if</rowType>
                <optionalElement>message contains more data</optionalElement>
                    <fieldName>Character Set</fieldName>
                    <DTLink>
                        <DTLinkL>int(2)</DTLinkL>
                        <DTLinkT>int(2)</DTLinkT>
                    </DTLink>
                    <fieldValue>2</fieldValue>
                    <descriptionWithLink>
                        <Description>The value is ignored. This have been proven in tests
                            against 5.1.23. In 5.7 the field doesn't arrive. Further research
                            is needed to identify if UUT information presents in the message
                        </Description>
                    </descriptionWithLink>
            </infoTable>
    

    然后,在 XSL 中做一个:

                                <xsl:for-each select="m:infoTable">
                                <xsl:variable name="MessageID" select="m:id" />
                                <xsl:choose>
                                    <xsl:when test="m:rowType='header'">
                                        <tr>
                                            <td colspan="5">
                                                <a href="#header">Header</a>
                                            </td>
                                        </tr>
                                    </xsl:when>
                                    <xsl:when test="m:rowType='if'">
                                        <tr>
                                            <td bgcolor="#E0FFFF" colspan="5">
                                                if {
                                                <xsl:value-of select="m:optionalElement" />
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>
                                                <xsl:value-of select="m:fieldName" />
                                            </td>
                                            <td>
                                                <xsl:variable name="DTLinkV"
                                                    select="m:DTLink/m:DTLinkL" />
                                                <a href="#{$DTLinkV}">
                                                    <xsl:value-of select="m:DTLink/m:DTLinkT" />
                                                </a>
                                            </td>
                                            <td>
                                                <xsl:value-of select="m:fieldSize" />
                                            </td>
                                            <td>
                                                <xsl:value-of select="m:fieldValue" />
                                            </td>
                                            <td>
                                                <xsl:value-of
                                                    select="m:descriptionWithLink/m:Description" />
                                                <br />
                                                <xsl:if test="m:descriptionWithLink/m:XLink">
                                                    <xsl:variable name="XLinkV"
                                                        select="m:descriptionWithLink/m:XLink/m:XLinkL" />
                                                    <a href="{$XLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:XLink/m:XLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:DLink">
                                                    <xsl:variable name="DLinkV"
                                                        select="m:descriptionWithLink/m:DLink/m:DLinkL" />
                                                    <a href="#{$DLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:DLink/m:DLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:MLink">
                                                    <xsl:variable name="MLinkV"
                                                        select="m:descriptionWithLink/m:MLink/m:MLinkL" />
                                                    <a href="#{$MLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:MLink/m:MLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:DTLink">
                                                    <xsl:variable name="DTLinkV"
                                                        select="m:descriptionWithLink/m:DTLink/m:DTLinkL" />
                                                    <a href="#{$DTLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:DTLink/m:DTLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:SLink">
                                                    <xsl:variable name="SLinkV"
                                                        select="m:descriptionWithLink/m:SLink/m:SLinkL" />
                                                    <a href="#{$SLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:SLink/m:SLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td bgcolor="f8ffff" colspan="5"> }</td>
                                        </tr>
                                    </xsl:when>
                                    <xsl:when test="m:rowType='else'">
                                        <tr>
                                            <td bgcolor="#E0FFFF" colspan="5">
                                                else {
                                                <xsl:value-of select="m:optionalElement" />
                                            </td>
                                        </tr>
                                        <tr>
                                            <td>
                                                <xsl:value-of select="m:fieldName" />
                                            </td>
                                            <td>
                                                <xsl:variable name="DTLinkV"
                                                    select="m:DTLink/m:DTLinkL" />
                                                <a href="#{$DTLinkV}">
                                                    <xsl:value-of select="m:DTLink/m:DTLinkT" />
                                                </a>
                                            </td>
                                            <td>
                                                <xsl:value-of select="m:fieldSize" />
                                            </td>
                                            <td>
                                                <xsl:value-of select="m:fieldValue" />
                                            </td>
                                            <td>
                                                <xsl:value-of
                                                    select="m:descriptionWithLink/m:Description" />
                                                <br />
                                                <xsl:if test="m:descriptionWithLink/m:XLink">
                                                    <xsl:variable name="XLinkV"
                                                        select="m:descriptionWithLink/m:XLink/m:XLinkL" />
                                                    <a href="{$XLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:XLink/m:XLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:DLink">
                                                    <xsl:variable name="DLinkV"
                                                        select="m:descriptionWithLink/m:DLink/m:DLinkL" />
                                                    <a href="#{$DLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:DLink/m:DLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:MLink">
                                                    <xsl:variable name="MLinkV"
                                                        select="m:descriptionWithLink/m:MLink/m:MLinkL" />
                                                    <a href="#{$MLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:MLink/m:MLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:DTLink">
                                                    <xsl:variable name="DTLinkV"
                                                        select="m:descriptionWithLink/m:DTLink/m:DTLinkL" />
                                                    <a href="#{$DTLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:DTLink/m:DTLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:SLink">
                                                    <xsl:variable name="SLinkV"
                                                        select="m:descriptionWithLink/m:SLink/m:SLinkL" />
                                                    <a href="#{$SLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:SLink/m:SLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                            </td>
                                        </tr>
                                        <tr>
                                            <td bgcolor="f8ffff" colspan="5"> }</td>
                                        </tr>
                                    </xsl:when>
                                    <xsl:otherwise>
                                        <tr>
                                            <td>
                                                <xsl:value-of select="m:fieldName" />
                                            </td>
                                            <td>
                                                <xsl:variable name="DTLinkV"
                                                    select="m:DTLink/m:DTLinkL" />
                                                <a href="#{$DTLinkV}">
                                                    <xsl:value-of select="m:DTLink/m:DTLinkT" />
                                                </a>
                                            </td>
                                            <td>
                                                <xsl:value-of select="m:fieldSize" />
                                            </td>
                                            <td>
                                                <xsl:value-of select="m:fieldValue" />
                                            </td>
                                            <td>
                                                <xsl:value-of
                                                    select="m:descriptionWithLink/m:Description" />
                                                <br />
                                                <xsl:if test="m:descriptionWithLink/m:XLink">
                                                    <xsl:variable name="XLinkV"
                                                        select="m:descriptionWithLink/m:XLink/m:XLinkL" />
                                                    <a href="{$XLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:XLink/m:XLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:DLink">
                                                    <xsl:variable name="DLinkV"
                                                        select="m:descriptionWithLink/m:DLink/m:DLinkL" />
                                                    <a href="#{$DLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:DLink/m:DLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:MLink">
                                                    <xsl:variable name="MLinkV"
                                                        select="m:descriptionWithLink/m:MLink/m:MLinkL" />
                                                    <a href="#{$MLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:MLink/m:MLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:DTLink">
                                                    <xsl:variable name="DTLinkV"
                                                        select="m:descriptionWithLink/m:DTLink/m:DTLinkL" />
                                                    <a href="#{$DTLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:DTLink/m:DTLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                                <xsl:if test="m:descriptionWithLink/m:SLink">
                                                    <xsl:variable name="SLinkV"
                                                        select="m:descriptionWithLink/m:SLink/m:SLinkL" />
                                                    <a href="#{$SLinkV}">
                                                        <xsl:value-of
                                                            select="m:descriptionWithLink/m:SLink/m:SLinkT" />
                                                    </a>
                                                    <br />
                                                </xsl:if>
                                            </td>
                                        </tr>
                                    </xsl:otherwise>
                                </xsl:choose>
                            </xsl:for-each>
    

    结果确实是:

    【讨论】:

      猜你喜欢
      • 2010-12-23
      • 2021-02-27
      • 1970-01-01
      • 2020-04-11
      • 1970-01-01
      • 2018-02-04
      • 2017-01-16
      • 1970-01-01
      相关资源
      最近更新 更多