【问题标题】:XPath how to create a path to an attribute dynamicallyXPath 如何动态创建属性的路径
【发布时间】:2017-06-14 23:05:52
【问题描述】:

我正在制作一个表格,其中标题名称来自 header 元素,数据来自 reportdataattributes元素。但是,我不知道属性的名称:Value1, Value2, ect..。属性的名称被生成并存储到 FieldName 属性中,该属性位于 reportnode 内的 column 元素内。

我还没有找到一种方法来制作使用生成的 FieldNames 并从 reportdata 获取相应属性值的 XPath。有任何想法吗?或者这是不可能的。

以下是 XML:

<report>
    <reportparameters>
        <header Order="1" HeaderName="Day_1" />
        <header Order="2" HeaderName="Day_2" />
        <header Order="3" HeaderName="Day_3" />
        <header Order="4" HeaderName="Total" />

        <reportnode ColumnCount="4">
            <column Order="1" FieldName="Value1" />
            <column Order="2" FieldName="Value2" />
            <column Order="3" FieldName="Value3" />
            <column Order="4" FieldName="TotalValue" />
        </reportnode>
    </reportparameters>

    <reportdata Value1="0" Value2="0" Value3="0" TotalValue="0"/>
    <reportdata Value1="0" Value2="0" Value3="0" TotalValue="0"/>
    <reportdata Value1="0" Value2="0" Value3="0" TotalValue="0"/>
    <reportdata Value1="0" Value2="0" Value3="0" TotalValue="0"/>
    <reportdata Value1="0" Value2="0" Value3="0" TotalValue="0"/>
</report>

XSL 尝试:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="xml" indent="no"/>
    <xsl:template match="/">
        <report>       
            <row>
                <xsl:for-each select="/report/reportparameters/header">
                    <xsl:variable name="columnCounter" select="position()"/>
                    <xsl:element name="{./@HeaderName}">
                    <xsl:for-each select="/report/reportdata">
                        <xsl:value-of select="@{../reportparameters/reportnode/column[@Order=$columnCounter+1]/@FieldName}"/>
                    </xsl:for-each>
                    </xsl:element>
                </xsl:for-each>
            </row>
        </report>
    </xsl:template>
</xsl:stylesheet>

【问题讨论】:

  • 你想要得到什么结果?请使用不同的单元格值,以便我们理解转换的逻辑。
  • @michael.hor257k 我一定会确保下次发布我想要的结果。幸运的是,没有它你仍然能够帮助我!

标签: xml xslt xpath xslt-1.0


【解决方案1】:

我怀疑你可以这样做:

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="/report">
    <xsl:variable name="cols" select="reportparameters/reportnode/column" />
    <report> 
        <xsl:for-each select="reportdata">
            <row>
                <xsl:for-each select="@*">
                    <xsl:variable name="i" select="position()"/>
                    <xsl:element name="{$cols[$i]/@FieldName}">
                        <xsl:value-of select="."/>
                    </xsl:element>
                </xsl:for-each>
            </row>
        </xsl:for-each>
    </report>
</xsl:template>

</xsl:stylesheet>

得到:

<?xml version="1.0" encoding="UTF-8"?>
<report>
  <row>
    <Value1>0</Value1>
    <Value2>0</Value2>
    <Value3>0</Value3>
    <TotalValue>0</TotalValue>
  </row>
  <row>
    <Value1>0</Value1>
    <Value2>0</Value2>
    <Value3>0</Value3>
    <TotalValue>0</TotalValue>
  </row>
  <row>
    <Value1>0</Value1>
    <Value2>0</Value2>
    <Value3>0</Value3>
    <TotalValue>0</TotalValue>
  </row>
  <row>
    <Value1>0</Value1>
    <Value2>0</Value2>
    <Value3>0</Value3>
    <TotalValue>0</TotalValue>
  </row>
  <row>
    <Value1>0</Value1>
    <Value2>0</Value2>
    <Value3>0</Value3>
    <TotalValue>0</TotalValue>
  </row>
</report>

这是假设每个reportdata 具有相同的属性,以相同的顺序,对应于column 元素在reportnode 中的顺序。否则会稍微复杂一些。

OTOH,如果 - 如您的示例所示 - reportdata 的属性具有所需的名称,则可以更简单:

<xsl:template match="/report">
    <report> 
        <xsl:for-each select="reportdata">
            <row>
                <xsl:for-each select="@*">
                    <xsl:element name="{name()}">
                        <xsl:value-of select="."/>
                    </xsl:element>
                </xsl:for-each>
            </row>
        </xsl:for-each>
    </report>
</xsl:template>

【讨论】:

  • 第一个解决方案效果很好,但您的第二个解决方案让我思考为什么我没有那样格式化我的 xml。我对构建 XML 的方式进行了一些更改,使其更直观,现在我可以使用您的第二个解决方案。非常感谢!
猜你喜欢
  • 1970-01-01
  • 2013-12-24
  • 1970-01-01
  • 1970-01-01
  • 2019-06-08
  • 2019-04-12
  • 2023-03-16
  • 2018-07-03
  • 2012-02-01
相关资源
最近更新 更多