使用 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
Retrieve all the attribute values from XML using XSLT
提问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.
这应该是一个足够的提示,让你弄清楚事情。如果您有任何其他问题,请告诉我。

