使用 XSLT 从 XML 检索所有属性值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16569431/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-06 14:01:24  来源:igfitidea点击:

Retrieve all the attribute values from XML using XSLT

xmlxsltvalue-of

提问by Erik ?strand

I can't figure out how to access all the attributes in a tag from an XML document.

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

Let's say I have the following XML:

假设我有以下 XML:

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

I want the following output: Rocky Balboa, Ivan Drago,

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

What I currently have is:

我目前拥有的是:

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

What I'm wondering is if it's possible to do this in just one value-of select instead of having to do three of them. So to clarify, I want to be able to output all the attributes in the tag with one single value-of select. Is this possible?

我想知道的是,是否有可能只在一个值中执行此操作,而不必执行其中三个。所以澄清一下,我希望能够用一个单一的选择值输出标签中的所有属性。这可能吗?

Thanks.

谢谢。

回答by hr_117

Because I'm not sure if the use of xsl:value-ofis a hard requirement, perhaps something like the following could be what you are locking for.

因为我不确定使用 ofxsl: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>

You can use <xsl:apply-templates select="names/name" mode="print"/>at any position you have considered about using a one line value-of for all attributes.
The above template will generate the following output:

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

Rocky Balboa, Ivan Drago,

Update crate output without using the attribute names:

不使用属性名称更新 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>

回答by james31rock

try the following:

尝试以下操作:

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

回答by Daniel Haley

If you can use XSLT 2.0, you can do something like this:

如果您可以使用 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>

This will output all attributes and you have no control over the order, so if you want to specify an order, you can either use a sequence:

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

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

or do an xsl:apply-templateswith an xsl:sortto sort the attributes by name()(or whatever). Let me know if you'd like an example.

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

回答by Michael Kay

The following works in XSLT 2.0:

以下在 XSLT 2.0 中有效:

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

and in 3.0 you can do:

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

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

though you may need to make adjustments to get the whitespace the way you want it.

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

回答by user1188611

You can use this XPath @* to get all attributes, e.g.:

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

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

This will let you use just one value-of select to get the output you want. It will take all attribute into consideration.

这将让您只使用一个选择值来获得您想要的输出。它将考虑所有属性。

This should be a sufficient hint for you to figure out things. Let me know if you have any other question.

这应该是一个足够的提示,让你弄清楚事情。如果您有任何其他问题,请告诉我。