xml + xsl 中获取 xpath 的问题

zjcxc 2007-06-10 01:53:27
本人在做一个数据处理的时候, 需要实现类似下面的一个处理:
有一个 xml, 类似下面的结构
<root>
<rr name="a">
<rrr>a1</rrr>
<rrr>a2</rrr>
<rrr>a3</rrr>
<rrr>a4</rrr>
</rr>
<rr name="b">
<rrr>b1</rrr>
<rrr>b2</rrr>
<rrr>b3</rrr>
<rrr>b4</rrr>
</rr>
</root>


需要写一个 xsl 文件, 将其显示为类似这样的效果:

- Libary: a
value: a1 (/root/rr[1]/rrr[1])
value: a2 (/root/rr[1]/rrr[2])
value: a3 (/root/rr[1]/rrr[3])
value: a4 (/root/rr[1]/rrr[4])

- Libary: b
value: b1 (/root/rr[2]/rrr[1])
value: b2 (/root/rr[2]/rrr[2])
value: b3 (/root/rr[2]/rrr[3])
value: b4 (/root/rr[2]/rrr[4])

----------------------------------------------
对于显示成如上格式来说, 用 xsl 可以很容易的实现, 但有如下两个需求不知道如何实现:

1. 对于 Libary, 需要可以实现折叠的效果, 即默认情况下, 是不 Value 数据的, 仅显示为:
+ Libary: a
+ Libary: b
只有单击 + 号才显示出 value 的数据

2. 对于每个 value, 其后面的: (/root/rr[2]/rrr[1])
这样的信息是该 value 对应于 xml 数据的 xpath, 通过这个 xpath, 可以唯一定位到这个 value. 并且需要显示为 value 的超链接接, 该超链接接的URL即为 xpath(即显示的时间, value 项中, 括号部分的值是为显示的, 仅仅是 value 各值上有一个超链接, 超链接的 URL 地址为 xpth(括号中显示的内容))


注: 因为需求的限制, 所以如果涉及到脚本, 则仅限 java 脚本, 而且是嵌入在 xsl 文件中的
...全文
840 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
cds27 2007-06-27
  • 打赏
  • 举报
回复
来了,最近比较忙没什么上。

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="gb2312" omit-xml-declaration="yes"/>
<xsl:template match="/">
<html>
<head>
<title></title>
<script type="text/javascript" language="javascript">
<![CDATA[
function btnOnClick(obj) {
if(obj.innerText=="+") {
theChild=obj.parentElement.nextSibling;
theChild.style.display="";
obj.innerText="-";
}
else {
theChild=obj.parentElement.nextSibling;
theChild.style.display="none";
obj.innerText="+";
}
}
]]>
</script>
</head>
<body>
<xsl:apply-templates select="root/*" />
</body>
</html>
</xsl:template>


<xsl:template match="*">
<xsl:param name="parentXpath">/root</xsl:param>
<xsl:variable name="name" select="name()"/>
<xsl:variable name="currXpath"><xsl:value-of select="$parentXpath"/>/<xsl:value-of select="name()"/>[<xsl:value-of select="count(preceding-sibling::*[name()=$name])+1"/>]</xsl:variable>
<div style="margin: 3px 3px 6px 6px;
padding: 1px 1px 1px 5px;
vertical-align: top;
border-bottom: 1px outset #999999;
border-left: 1px dotted #999999;">
<xsl:if test="*">
<div><span id="" onclick="btnOnClick(this)" style="cursor: pointer;">+</span> Libary: <xsl:value-of select="@name"/></div>
<div style="display: none;">
<xsl:apply-templates>
<xsl:with-param name="parentXpath" select="$currXpath"/>
</xsl:apply-templates>
</div>
</xsl:if>
<xsl:if test="not(*)">
<div style="margin-left: 5px">
value: <xsl:value-of select="."/> (<xsl:value-of select="$currXpath"/>)

</div>
</xsl:if>
</div>
</xsl:template>

</xsl:stylesheet>
zjcxc 2007-06-22
  • 打赏
  • 举报
回复
那就劳你费心了
zfangel 2007-06-22
  • 打赏
  • 举报
回复
很简单,就是要费点时间
zjcxc 2007-06-22
  • 打赏
  • 举报
回复
- Libary: a
value: a1 (/root/rr[1] /rrr[1] ) value: a1
value: a2 (/root/rr[1] /rrr[2] ) value: a2
value: a3 (/root/rr[1] /rrr[3] ) value: a3
value: a4 (/root/rr[1] /rrr[4] ) value: a4
- Libary: b
value: b1 (/root/rr[2] /rrr[1] ) value: b1
value: b2 (/root/rr[2] /rrr[2] ) value: b2
value: b3 (/root/rr[2] /rrr[3] ) value: b3
value: b4 (/root/rr[2] /rrr[4] ) value: b4
- Libary:
- Libary: a
value: a1 (/root/root_child[3] /rr[1] /rrr[1] ) value: a1 -- 正确的应该是:(/root/root_child[1] /rr[1] /rrr[1], 后面的也是
value: a2 (/root/root_child[3] /rr[1] /rrr[2] ) value: a2
value: a3 (/root/root_child[3] /rr[1] /rrr[3] ) value: a3
value: a4 (/root/root_child[3] /rr[1] /rrr[4] ) value: a4
- Libary: b
value: b1 (/root/root_child[3] /rr[2] /rrr[1] ) value: b1
value: b2 (/root/root_child[3] /rr[2] /rrr[2] ) value: b2
value: b3 (/root/root_child[3] /rr[2] /rrr[3] ) value: b3
value: b4 (/root/root_child[3] /rr[2] /rrr[4] ) value: b4
cds27 2007-06-22
  • 打赏
  • 举报
回复
你指的是什么不对?
告诉我个正确的。
zjcxc 2007-06-18
  • 打赏
  • 举报
回复

郁闷, 我用 visual studio 测试的, 最后直接在 xml 文件中加入指令用浏览器来显示是正常的.
那就只有下面的问题了
下面这个能解决么?

- Libary: a
value: a1 (/root/rr[1] /rrr[1] ) value: a1
value: a2 (/root/rr[1] /rrr[2] ) value: a2
value: a3 (/root/rr[1] /rrr[3] ) value: a3
value: a4 (/root/rr[1] /rrr[4] ) value: a4
- Libary: b
value: b1 (/root/rr[2] /rrr[1] ) value: b1
value: b2 (/root/rr[2] /rrr[2] ) value: b2
value: b3 (/root/rr[2] /rrr[3] ) value: b3
value: b4 (/root/rr[2] /rrr[4] ) value: b4
- Libary:
- Libary: a
value: a1 (/root/root_child[3] /rr[1] /rrr[1] ) value: a1 -- 这个能改吗? 这个不对
value: a2 (/root/root_child[3] /rr[1] /rrr[2] ) value: a2
value: a3 (/root/root_child[3] /rr[1] /rrr[3] ) value: a3
value: a4 (/root/root_child[3] /rr[1] /rrr[4] ) value: a4
- Libary: b
value: b1 (/root/root_child[3] /rr[2] /rrr[1] ) value: b1
value: b2 (/root/root_child[3] /rr[2] /rrr[2] ) value: b2
value: b3 (/root/root_child[3] /rr[2] /rrr[3] ) value: b3
value: b4 (/root/root_child[3] /rr[2] /rrr[4] ) value: b4


cds27 2007-06-18
  • 打赏
  • 举报
回复
那个XML我在我机器上XMLSPY测试,结果很正常。
也没出现
value: a1 (/root/rr[1]/rrr[2]) -- 应该是 1~4
value: a2 (/root/rr[1]/rrr[4])
...
的问题
zjcxc 2007-06-14
  • 打赏
  • 举报
回复
就用你的回复前面我帖出的 xml 数据

谢谢
zjcxc 2007-06-14
  • 打赏
  • 举报
回复
就用你回复的前面我帖出的那个 xml 数据
zjcxc 2007-06-14
  • 打赏
  • 举报
回复
就用你的回复前面我帖出的那个 xml
cds27 2007-06-13
  • 打赏
  • 举报
回复
value: <xsl:value-of select="."/> (<xsl:value-of select="$currXpath"/>)
改超连接:
value: <a href="{$currXpath}"> <xsl:value-of select="."/> </a>


另外,你把有问题的XML贴给我看下。
cds27 2007-06-12
  • 打赏
  • 举报
回复
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" encoding="gb2312" omit-xml-declaration="yes"/>
<xsl:template match="/">
<html>
<head>
<title></title>
<script type="text/javascript" language="javascript">
<![CDATA[
function btnOnClick(obj) {
if(obj.innerText=="+") {
theChild=obj.parentElement.nextSibling;
theChild.style.display="";
obj.innerText="-";
}
else {
theChild=obj.parentElement.nextSibling;
theChild.style.display="none";
obj.innerText="+";
}
}
]]>
</script>
</head>
<body>
<xsl:apply-templates select="root/*" />
</body>
</html>
</xsl:template>


<xsl:template match="*">
<xsl:param name="parentXpath">/root</xsl:param>
<xsl:variable name="currXpath"><xsl:value-of select="$parentXpath"/>/<xsl:value-of select="name()"/>[<xsl:value-of select="position()"/>]</xsl:variable>
<div style="margin: 3px 3px 6px 6px;
padding: 1px 1px 1px 5px;
vertical-align: top;
border-bottom: 1px outset #999999;
border-left: 1px dotted #999999;">
<xsl:if test="*">
<div><span id="" onclick="btnOnClick(this)" style="cursor: pointer;">+</span> Libary: <xsl:value-of select="@name"/></div>
<div style="display: none;">
<xsl:apply-templates>
<xsl:with-param name="parentXpath" select="$currXpath"/>
</xsl:apply-templates>
</div>
</xsl:if>
<xsl:if test="not(*)">
<div style="margin-left: 5px">
value: <xsl:value-of select="."/> (<xsl:value-of select="$currXpath"/>)
</div>
</xsl:if>
</div>
</xsl:template>

</xsl:stylesheet>
zjcxc 2007-06-12
  • 打赏
  • 举报
回复
另外, cds27 的已经实现递归, 但结果有问题, 例如下面的, 生成的 xpath 就正确

<root>
<rr name="a">
<rrr>a1</rrr>
<rrr>a2</rrr>
<rrr>a3</rrr>
<rrr>a4</rrr>
</rr>
<rr name="b">
<rrr>b1</rrr>
<rrr>b2</rrr>
<rrr>b3</rrr>
<rrr>b4</rrr>
</rr>
<root_child>
<rr name="a">
<rrr>a1</rrr>
<rrr>a2</rrr>
<rrr>a3</rrr>
<rrr>a4</rrr>
</rr>
<rr name="b">
<rrr>b1</rrr>
<rrr>b2</rrr>
<rrr>b3</rrr>
<rrr>b4</rrr>
</rr>
</root_child>
</root>
zjcxc 2007-06-12
  • 打赏
  • 举报
回复
谢谢 cds27(http://blog.csdn.net/cds27/)


不过结果有点不对, 我测试结果是:
- Libary: a
value: a1 (/root/rr[1]/rrr[2]) -- 应该是 1~4
value: a2 (/root/rr[1]/rrr[4])
value: a3 (/root/rr[1]/rrr[6])
value: a4 (/root/rr[1]/rrr[8])
- Libary: b
value: b1 (/root/rr[2]/rrr[2])
value: b2 (/root/rr[2]/rrr[4])
value: b3 (/root/rr[2]/rrr[6])
value: b4 (/root/rr[2]/rrr[8])



另外, ()中的内容希望变为前面 value 值的超链接的URL地址, 还需要请教如何实现
zjcxc 2007-06-10
  • 打赏
  • 举报
回复
补充:
实际应用的 xml 远比示例的复杂, 所以层次不是固定的 /root/rr/rrr
最好能够直接根据当前解析到的结点推导出其 xpath

8,906

社区成员

发帖
与我相关
我的任务
社区描述
XML/XSL相关问题讨论专区
社区管理员
  • XML/XSL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧