如何在XSLT中迭代未知列

时间:2009-03-23 20:27:33

标签: xslt xpath

标题几乎说明了一切。我有一个XML文档,我正在使用XSLT处理....但我不知道XML文档中有多少列(字段)(因此,显然,我不知道他们的名字)。 如何确定“未知”字段的数量?另外,如何读取未知字段的属性(如果有)?

示例数据......

<Dataset>
   <Row>
       <UnknownCol1 Msg="HowDoIGetThisMsgAttribute?"/>
       <UnknownCol2 />
       <UnknownCol3 />
   </Row>
</Dataset>

4 个答案:

答案 0 :(得分:2)

解决这个问题的方法很简单。

对于您提供的示例,您可以使用以下XPath:

select='/Dataset/Row/*/@Msg'

如果您想要一个更具体的例子,您可能希望更清楚地了解您想要对数据和未知列做什么。你正在复制它吗?您想具体将其转化为什么?你有任何你想要匹配的钥匙吗?

那种事。

答案 1 :(得分:2)

  

如何确定数量   “未知”字段有吗?

此XPath表达式

count(/*/*/*)

评估元素的数量,即作为XML文档顶级节点的子元素的子元素 - 在这种情况下正是所需的元素。

如果"Row"元素的子名称不以“UnknownCol”开头,

然后这个XPath表达式提供了元素的数量,其名称以“UnknownCol”开头,并且是作为top元素子元素的元素的子元素:

count(/*/*/*[starts-with(name(), "UnknownCol")])

如果top元素可能包含除"Row"之外的其他子元素,则提供所需计数的XPath表达式为:

count(/*/Row/*[starts-with(name(), "UnknownCol")])
  

另外,我该如何阅读属性,   如果有的话,对于未知领域?

了解XPath:)

/*/Row/*[starts-with(name(), "UnknownCol")]/@*

选择所有“UnknownCol”{String}元素的所有属性

这个XPath表达式为我们提供了这些属性的数量:

  count(/*/Row/*[starts-with(name(), "UnknownCol")]/@*)

这个Xpath表达式给出了第k个这样的属性的名称($ ind必须设置为数字k):

name( (/*/Row/*[starts-with(name(), "UnknownCol")]/@*)[$ind] )

最后,这个XPath表达式产生了第k个这样的属性的值:

string( (/*/Row/*[starts-with(name(), "UnknownCol")]/@*)[$ind] )

编辑:OP评论说他完全不知道子元素的名称

修复很简单:只需从所有表达式中删除谓词:

count(/*/*/*)

count(/*/Row/*)


/*/Row/*/@*


count(/*/Row/*/@*)

name( (/*/Row/*/@*)[$ind] )

string( (/*/Row/*/@*)[$ind] )

答案 2 :(得分:1)

以下是一小段XSLT 1.0代码示例,它将您的输入转换为HTML表格。

<xsl:template match="Dataset">
  <table>
    <thead>
      <tr>
        <xsl:apply-templates select="Row[1]/*" mode="th" />
      </tr>
    </thead>
    <tbody>
      <xsl:apply-templates select="Row" />
    </tbody>
  </table>
</xsl:template>

<xsl:template match="Row">
  <tr>
    <xsl:apply-templates select="*" mode="td" />
  </tr>
</xsl:template>

<xsl:template match="Row/*" mode="th">
  <th>
    <xsl:value-of select="local-name()" />
  </th>
</xsl:template>

<xsl:template match="Row/*" mode="td">
  <td>
    <xsl:value-of select="@Msg" />
  </td>
</xsl:template>

当应用于此样本输入时:

<Dataset>
  <Row>
    <UnknownCol1 Msg="Data_1_1" />
    <UnknownCol2 Msg="Data_1_2" />
    <UnknownCol3 Msg="Data_1_3" />
  </Row>
  <Row>
    <UnknownCol1 />
    <UnknownCol2 Msg="Data_2_2" />
    <UnknownCol3 Msg="" />
  </Row>
</Dataset>

返回此输出:

<table>
  <thead>
    <tr>
      <th>UnknownCol1</th>
      <th>UnknownCol2</th>
      <th>UnknownCol3</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Data_1_1</td>
      <td>Data_1_2</td>
      <td>Data_1_3</td>
    </tr>
    <tr>
      <td></td>
      <td>Data_2_2</td>
      <td></td>
    </tr>
  </tbody>
</table>

答案 3 :(得分:1)

这也可以帮助某人:

浏览以()AMT_开头的未知节点并检查其中是否有任何空

XML:

<INCOME_FARMING_OPERATIONS>
<PERSONAL_FARMING>
<IND_SCHEDULE>Y</IND_SCHEDULE>
<DESCRIPTION>FARMING OPERATIONS</DESCRIPTION>
<IDENTIFIER>111111111111</IDENTIFIER>
<AMT_FARM_INC_GROSS>22222222</AMT_FARM_INC_GROSS>
<AMT_FARM_INC_PARTNER></AMT_FARM_INC_PARTNER>
<AMT_BAL_LIVESTOCK>99999999</AMT_BAL_LIVESTOCK>
</PERSONAL_FARMING>
</INCOME_FARMING_OPERATIONS>

XSLT

<xsl:variable name ="NodeValueIsEmpty">
<xsl:for-each select ="//INCOME_FARMING_OPERATIONS/PERSONAL_FARMING/*[starts-with(name(),'AMT_')]">
<xsl:if test ="string-length(.)=0">
empty found
</xsl:if>
</xsl:for-each>
</xsl:variable>
<xsl:value-of select="$IncomeFieldValues"/>

输出: 因空而发现空 你可以进一步发展:

<xsl:if test=string-length($NodeValueIsEmpty)>0>
//todo if any of the AMT_???? fields is not set
</xsl:if>