标题几乎说明了一切。我有一个XML文档,我正在使用XSLT处理....但我不知道XML文档中有多少列(字段)(因此,显然,我不知道他们的名字)。 如何确定“未知”字段的数量?另外,如何读取未知字段的属性(如果有)?
示例数据......
<Dataset>
<Row>
<UnknownCol1 Msg="HowDoIGetThisMsgAttribute?"/>
<UnknownCol2 />
<UnknownCol3 />
</Row>
</Dataset>
答案 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>