【问题标题】:How to output value of a node that has attribute in XSLT?如何在 XSLT 中输出具有属性的节点的值?
【发布时间】:2020-09-03 04:26:42
【问题描述】:

如何获取XSL中带有属性的元素的值?

这是我用来测试代码的示例。

<CD>
        <a/> <!--N0#1-->
        <b>text</b> <!--NO#2-->
        <c YEAR="value"/> <!--NO#3-->
        <d name="value" ou="aous">9.90</d> <!--NO#4-->
        <e><f>text</f> <!--NO#5-->
            <g>text</g></e>
        <i><h>text</h> <!--NO#6-->
            <h>text</h></i>
</CD>

我希望这个 NO#4 部分给我这样的输出:

"d" : {
                
                            "@name" : "value",
                         
                           "@ou" : "aous",

                        "VALUE_VARIABLE":"9.90"
                }

我遇到的问题是我无法获得“9.90”元素。我怎样才能做到这一点?这是我的代码:

<xsl:for-each select="@*">
                    <xsl:choose>
                        <xsl:when test="position()=last()"> <!--check if current attribute is last-->
                           "@<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>"
                        </xsl:when>
                        <xsl:when test="./*"> <!--check if current element has child elements-->
                            "<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>"
                        </xsl:when>
                        <xsl:when test="(./*) and not(position()=last())">
                            "<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>",
                        </xsl:when>
                        <xsl:otherwise>
                            "@<xsl:value-of select="name()"/>" : "<xsl:value-of select="."/>",
                        </xsl:otherwise>
                    </xsl:choose>
                </xsl:for-each>

编辑 - here 你可以找到完整的代码。

【问题讨论】:

    标签: json xml xslt xslt-1.0


    【解决方案1】:

    试试这样的:

    <xsl:variable name="q">"</xsl:variable>
    <xsl:variable name="nl">&#xa;</xsl:variable>
    <xsl:template match="*[@*]">
      <xsl:value select="name()"/>{
      <xsl:for-each select="@*">
        <xsl:if test="position()!=1">,
    </xsl:if>
        <xsl:value-of select="concat($q, '@', name(), $q, ' : ', $q, ., $q)"/>
      </xsl:for-each>
      <xsl:value-of select="concat($q, 'VALUE_VARIABLE', $q, ' : ', $q, ., $q)"/>
    </xsl:template> 
    

    【讨论】:

      【解决方案2】:

      当您处于属性的上下文中时,您可以使用以下方法获取其父元素的字符串值:

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

      当然,从父元素本身的上下文中获取要容易得多,例如:

      <xsl:template match="d">
          <xsl:text>{"d" : {</xsl:text>
          <xsl:for-each select="@*">
              <xsl:text>"@</xsl:text>
              <xsl:value-of select="name()"/>
              <xsl:text>" : "</xsl:text>
              <xsl:value-of select="."/>
              <xsl:text>", </xsl:text>
          </xsl:for-each>
          <xsl:text>"VALUE_VARIABLE" : "</xsl:text>
          <xsl:value-of select="."/>
          <xsl:text>"}}</xsl:text>
      </xsl:template>
      

      附言

      <xsl:when test="./*">
      

      对于属性永远不会为真。


      添加:

      如果您想让它更通用,请尝试以下操作:

      <xsl:template match="*[@*]">
          <xsl:text>{"</xsl:text>
          <xsl:value-of select="name()"/>
          <xsl:text>" : {</xsl:text>
          <xsl:for-each select="@*">
              <xsl:text>"@</xsl:text>
              <xsl:value-of select="name()"/>
              <xsl:text>" : "</xsl:text>
              <xsl:value-of select="."/>
              <xsl:text>"</xsl:text>
              <xsl:if test="position()!=last()">
                  <xsl:text>, </xsl:text>
              </xsl:if>
          </xsl:for-each>
          <xsl:if test="text()">
              <xsl:text>, "VALUE_VARIABLE" : "</xsl:text>
              <xsl:value-of select="."/>
              <xsl:text>"</xsl:text>
          </xsl:if>
          <xsl:text>}}</xsl:text>
          <xsl:if test="position()!=last()">
              <xsl:text>, </xsl:text>
          </xsl:if>
      </xsl:template>
      

      【讨论】:

      • 我知道 test = "./*" 没有通过,这就是我正在努力解决的问题。它应该能够适用于任何输入,这就是我不能使用“match = specific_element”模板的原因。此 select=".." 有效,但我不确定如何在“when”语句中设置条件。我应该检查具有属性的元素是否有文本,并且对于每个我需要输出 "VALUE_VARIABLE": "that_value" 我显然做错了。
      • 我在我的答案中添加了一个更通用的模板。恐怕我无法涵盖您所有可能的情况,因为您只发布了代码的 sn-p。
      • 我编辑了我的问题,你可以在这里找到代码:pastebin.com/Z8XS93iS你能看一下吗?
      • 不,我不打算在这上面花那么多时间。相信你有足够的能力来完成你自己的。 -- 一般建议:通用转换需要大量工作,并且很少适合所有可能的场景。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多