6

我不知道如何从 XML 文档访问标记中的所有属性。

假设我有以下 XML:

<names>
  <name firstname="Rocky" lastname="Balboa" divider=", "/>
  <name firstname="Ivan" lastname="Drago" divider=", "/>
</names>

我想要以下输出: Rocky Balboa, Ivan Drago,

我目前拥有的是:

<xsl:for-each select="names/name">
   <xsl:value-of select="@firstname"/>
   <xsl:value-of select="@lastname"/>
   <xsl:value-of select="@divider"/>
</xsl:for-each>

我想知道的是,是否有可能只用一个 value-of 选择来做到这一点,而不必做三个。所以为了澄清,我希望能够用一个单一的选择值输出标签中的所有属性。这可能吗?

谢谢。

4

5 回答 5

6

尝试以下操作:

<xsl:template match="/">
 <xsl:for-each select="names/name/@*">
        <xsl:value-of select="concat( ., ' ')"/>
  </xsl:for-each>
</xsl:template>     
于 2013-05-15T19:15:11.253 回答
3

因为我不确定使用是否xsl:value-of是一个硬性要求,所以可能像下面这样的东西可能是你要锁定的。

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

    <xsl:template match="name" mode ="print" >
        <xsl:value-of select="@firstname"/>
        <xsl:text> </xsl:text>
        <xsl:value-of select="@lastname"/>
        <xsl:value-of select="@divider"/>
    </xsl:template>

    <xsl:template match="/">
        <xsl:apply-templates  select="names/name" mode="print"/>
    </xsl:template>

</xsl:stylesheet>

您可以<xsl:apply-templates select="names/name" mode="print"/> 在您考虑过对所有属性使用单行值的任何位置使用。
上面的模板将生成以下输出:

Rocky Balboa, Ivan Drago,

在不使用属性名称的情况下更新 crate 输出:

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

    <xsl:template match="name" mode ="print" >
        <xsl:for-each select="@*" >
            <xsl:if test="not(position() = last() or position() = 1)">
                <xsl:text> </xsl:text>
            </xsl:if>
            <xsl:value-of select="."/>

        </xsl:for-each>
    </xsl:template>

    <xsl:template match="/">
        <xsl:apply-templates  select="names/name" mode="print"/>
    </xsl:template>

</xsl:stylesheet>
于 2013-05-15T17:07:03.720 回答
1

您可以使用此 XPath @* 来获取所有属性,例如:

<xsl:template match="/*">
    <xsl:for-each select="@*">
        <xsl:value-of select="concat(name(), ': ', ., ' ')"/>
    </xsl:for-each>
</xsl:template>

这将让您只使用一个 value-of select 来获得您想要的输出。它将考虑所有属性。

这应该足以让您弄清楚事情。如果您还有其他问题,请告诉我。

于 2013-05-15T16:47:47.203 回答
0

如果您可以使用 XSLT 2.0,您可以执行以下操作:

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>

    <xsl:template match="text()"/>

    <xsl:template match="*[@*]">
        <xsl:value-of select="@*[not(name()='divider')]" separator=" "/>
        <xsl:value-of select="@divider"/>           
        <xsl:apply-templates/>
    </xsl:template>

</xsl:stylesheet>

这将输出所有属性,并且您无法控制顺序,因此如果要指定顺序,可以使用序列:

<xsl:value-of select="(@firstname,@lastname)" separator=" "/>

xsl:apply-templates用 anxsl:sort对属性进行排序name()(或其他)。如果你想要一个例子,请告诉我。

于 2013-05-15T17:27:52.113 回答
0

以下适用于 XSLT 2.0:

<xsl:for-each select="names/name">
   <xsl:value-of select="@firstname, @lastname, @divider"/>
</xsl:for-each>

在 3.0 中,您可以执行以下操作:

<xsl:value-of select="names/name!(@firstname, @lastname, @divider)"/>

尽管您可能需要进行调整以按照您想要的方式获得空白。

于 2013-05-15T17:28:06.060 回答