尝试读取 xsl 中的 xml 元素值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16019678/
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 13:58:46  来源:igfitidea点击:

Trying to read xml element value in xsl

xmlxsltxslt-1.0

提问by user1818397

I am new to XSL. I am trying to read values of XML elements using a XSL file. My XML file is like:

我是XSL 的新手。我正在尝试使用 XSL 文件读取 XML 元素的值。我的 XML 文件是这样的:

<PersonList>
  <Person>
    <Name>person1</Name>
    <Age>21</Age>
  </Person>
  <Person>
    <Name>person2</Name>
    <Age>21</Age>
  </Person>
</PersonList>

My XSL file is like:

我的 XSL 文件是这样的:

<xsl:stylesheet version="1.0" xmlns=...>
  <xsl:output method="xml" indent="yes" encoding="utf-8" omit-xml declaration="no" />
  <xsl template match="/">
    <PersonList>
      <xsl:for-each select="PersonList/Person">
        <Person>
          <xsl:for-each select="*">
            <xsl:variable name="elementName">
              <xsl:value-of select="name(.)" />
            </xsl:variable>
            <xsl:variable name="elementValue">
              ???
            </xsl:variable>
          </xsl:for-each>
        </Person>
      </xsl:for-each>
    </PersonList> 
  </xsl:template>
</xsl:stylesheet>

How should I replace ???to get the value of the element stored in the elementNamevariable. I tried the following three lines separately:

我应该如何替换???以获取存储在elementName变量中的元素的值。我分别尝试了以下三行:

<xsl:value-of select="value(.)" /> 
<xsl:value-of select="value($elementName)" />
<xsl:value-of select="$elementName" />

but no luck. Please help!

但没有运气。请帮忙!

回答by Francis Avila

Your ??????????????????can be <xsl:value-of select="."/>(i.e. the string-value of the context element.) It has no connection to $elementName.

??????????????????可以是<xsl:value-of select="."/>(即上下文元素的字符串值。)它与$elementName.

You can do this much more succinctly like this:

你可以像这样更简洁地做到这一点:

<xsl:for-each select="*">
  <xsl:variable name="elementName" select="name()"/>
  <xsl:variable name="elementValue" select="string(.)"/>
</xsl:for-each>

However your template is really strange. You're collecting these variables but you're not doing anything with them--they won't appear in the output. What output are you trying to get?

但是你的模板真的很奇怪。您正在收集这些变量,但您没有对它们做任何事情——它们不会出现在输出中。你想得到什么输出?

Use of for-eachis generally a code smell. In almost all cases you're better off with multiple templates:

使用的for-each一般是代码异味。在几乎所有情况下,您最好使用多个模板:

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

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="Person/*">
    <xsl:variable name="elementName" select="name()"/>
    <xsl:variable name="elementValue" select="string(.)"/>
</xsl:template>

</xsl:stylesheet>

This pattern where you copy almost everything and change just a little bit of the xml is very common and very powerful and you should learn how to use it.

这种复制几乎所有内容并仅更改一点点 xml 的模式非常常见且非常强大,您应该学习如何使用它

回答by Tim C

Well, if you really wanted to get the value of an element whose name is held in a variable, in your case you would do it like this

好吧,如果您真的想获取名称保存在变量中的元素的值,那么在您的情况下,您可以这样做

<xsl:variable name="elementValue">
    <xsl:value-of select="../*[name()=$elementName]" />
</xsl:variable>

But, this is greatly overcomplicated matters. You are in a xsl:for-eachloop, iterating over the child elements of a Person. Therefore, because you are already positioned on the element for which you want the value, you can just do this and forget about the elementNamevariable.

但是,这是非常复杂的事情。您在xsl:for-each循环中,迭代Person的子元素。因此,因为您已经定位在您想要其值的元素上,所以您可以只执行此操作而忘记elementName变量。

<xsl:variable name="elementValue">
    <xsl:value-of select="."/>
</xsl:variable>

In fact, in you could simplify your loops to just this

实际上,您可以将循环简化为这样

<xsl:for-each select="PersonList/Person">
   <Person>
      <xsl:for-each select="*">
         <xsl:value-of select="." />
      </xsl:for-each>
   </Person>
</xsl:for-each>