Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >在XSLT中使用document()交叉引用和扩充XML元素的问题

在XSLT中使用document()交叉引用和扩充XML元素的问题
EN

Stack Overflow用户
提问于 2012-04-17 18:41:20
回答 1查看 544关注 0票数 3

我是一个XML新手,我有一个问题,我有一个已经生成的XML文档,其中一些元素的属性列表是不完整的。我正在尝试实现一个XSLT样式表,它用一个主文档交叉引用它(所有属性都有缺省值),以便用缺省值填充任何缺失的属性。

例如,以以下不完整的XML文档为例:

代码语言:javascript
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<foo>
  <bar label="two" index="2"/>
</foo>

bar元素缺少一个属性'type‘,我想根据’label‘的值从下面的主控文档中填充一个默认值:

代码语言:javascript
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<foo>
  <bar label="one" index="1" type="type1"/>
  <bar label="two" index="2" type="type2"/>
  <bar label="three" index="3" type="type3"/>
</foo>

期望的结果将是:

代码语言:javascript
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<foo>
  <bar label="two" index="2" type="type2"/>
</foo>

我的XSLT样式表尝试使用'document()‘和XPath的组合来实现这一点,如下所示:

代码语言:javascript
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

  <xsl:variable name="master" select="document('master.xml')"/>

  <!-- Template matching 'root' of XML document -->
  <xsl:template match="/">
    <xsl:apply-templates select="foo"/>
  </xsl:template>

  <!-- Template for generating 'foo' element -->
  <xsl:template match="foo">
    <foo>
      <xsl:apply-templates select="bar"/>
    </foo>
  </xsl:template>

  <!-- Template for generating 'bar' element -->
  <xsl:template match="bar">
    <bar label="{@label}" index="{@index}" type="{$master/foo/bar[@label=@label][1]/@type}"/>
  </xsl:template>

</xsl:stylesheet>

然而,这不起作用,并为'bar‘元素提供了默认的'type’属性,其中'label‘为'one’,而不是'two':

代码语言:javascript
运行
AI代码解释
复制
<?xml version="1.0" encoding="utf-8"?>
<foo>
  <bar label="two" index="2" type="type1"/>
</foo>

一些调查显示,XPath模式匹配所有的“bar”元素,而不仅仅是正确的元素,但我不确定为什么。

我做错了什么?有没有更好的方法?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-04-18 01:37:14

问题出在这一行

代码语言:javascript
运行
AI代码解释
复制
<bar label="{@label}" index="{@index}" 
     type="{$master/foo/bar[@label=@label][1]/@type}"/> 

您实际上是在检查bar元素的label属性是否等于其本身--这等同于:

代码语言:javascript
运行
AI代码解释
复制
<bar label="{@label}" index="{@index}" 
     type="{$master/foo/bar[true()][2]/@type}"/> 

,这等同于

代码语言:javascript
运行
AI代码解释
复制
<bar label="{@label}" index="{@index}" 
     type="{$master/foo/bar[1]/@type}"/> 

这就是你观察到的结果是如何产生的。

XSLT Solution:使用 函数:

代码语言:javascript
运行
AI代码解释
复制
<bar label="{@label}" index="{@index}" 
     type="{$master/foo/bar[@label=current()/@label][4]/@type}"/> 

完整的转换为(我已将URL更改为master.xml,以便能够在本地计算机上运行转换):

代码语言:javascript
运行
AI代码解释
复制
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

      <xsl:variable name="master" select=
      "document('file:///c:/temp/delete/master.xml')"/>

      <!-- Template matching 'root' of XML document -->
      <xsl:template match="/">
        <xsl:apply-templates select="foo"/>
      </xsl:template>

      <!-- Template for generating 'foo' element -->
      <xsl:template match="foo">
        <foo>
          <xsl:apply-templates select="bar"/>
        </foo>
      </xsl:template>

      <!-- Template for generating 'bar' element -->
      <xsl:template match="bar">
        <bar label="{@label}" index="{@index}"
        type="{$master/foo/bar[@label=current()/@label][5]/@type}"/>
      </xsl:template>
</xsl:stylesheet>

XML以及何时在所提供的文档上应用此转换:

代码语言:javascript
运行
AI代码解释
复制
<foo>
    <bar label="two" index="2"/>
</foo>

生成所需的正确结果::

代码语言:javascript
运行
AI代码解释
复制
<foo><bar label="two" index="2" type="type2"/></foo>

II.使用 可能更有效的解决方案

代码语言:javascript
运行
AI代码解释
复制
<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kTypeByLabel" match="@type" use="../@label"/>

      <xsl:variable name="master" select=
      "document('file:///c:/temp/delete/master.xml')"/>

      <!-- Template matching 'root' of XML document -->
      <xsl:template match="/">
        <xsl:apply-templates select="foo"/>
      </xsl:template>

      <!-- Template for generating 'foo' element -->
      <xsl:template match="foo">
        <foo>
          <xsl:apply-templates select="bar"/>
        </foo>
      </xsl:template>

      <!-- Template for generating 'bar' element -->
      <xsl:template match="bar">
        <xsl:variable name="vCurrent" select="."/>
        <xsl:variable name="vDefault">
          <xsl:for-each select="$master">
            <xsl:value-of select=
                "key('kTypeByLabel', $vCurrent/@label)"/>
          </xsl:for-each>
        </xsl:variable>

        <bar label="{@label}" index="{@index}" type="{$vDefault}"/>
      </xsl:template>
</xsl:stylesheet>

当对(相同)提供的XML文档(上面)应用此转换时,将生成所需的正确结果

代码语言:javascript
运行
AI代码解释
复制
<foo>
   <bar label="two" index="2" type="type2"/>
</foo>
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10197084

复制
相关文章
XML 在SQLServer中的使用
SQL Server对于XML支持的核心在于XML数据的格式,这种数据类型可以将XML的数据存储于数据库的对象中,比如variables, columns, and parameters。当你用XML数据类型配置这些对象中的一个时,你指定类型的名字就像你在SQLServer 中指定一个类型一样。
全栈程序员站长
2022/07/11
6K0
XML 在SQLServer中的使用
SQL Server对于XML支持的核心在于XML数据的格式,这种数据类型可以将XML的数据存储于数据库的对象中,比如variables, columns, and parameters。当你用XML数据类型配置这些对象中的一个时,你指定类型的名字就像你在SQLServer 中指定一个类型一样。 XML的数据类型确保了你的XML数据被完好的构建保存,同时也符合ISO的标准。在定义一个XML数据类型之前,我们首先要知道它的几种限制,如下: 一个实例的XML列不能包含超过2GB的数据。 一个XML的列不能是索引
用户1217611
2018/01/30
7.8K0
Python模块的交叉引用(导入循环)问题分析
    首先交叉引用或是相互引用,实际上就是导入循环,关于导入循环的详细说明,可见我摘自《python核心编程》第二版的摘抄:Python导入循环方法。
党志强
2020/02/11
5.5K0
XML元素和属性
默认情况下,next()方法不检查是否存在与标记为必需的属性相对应的元素和属性。要使读取器检查此类元素和属性是否存在,请在调用Next()之前将读取器的CheckRequired属性设置为1。出于兼容性原因,此属性的默认值为0。
用户7741497
2022/07/04
1.4K0
添加和使用XSLT扩展函数
当出现错误时,XSLT处理器(Xalan或Saxon)执行当前错误处理程序的error()方法,将消息作为参数发送到该方法。类似地,当发生致命错误或警告时,XSLT处理器会根据需要执行datalError()或Warning()方法。
用户7741497
2022/07/05
4.4K0
在Java 中安全使用接口引用
Photo by Joseph Maxim Reskp on Unsplash 我使用Java 开发过很多项目,这其中包括一些Web 应用和Android 客户端应用。作为Android 开发人员,J
小鄧子
2019/03/05
1.9K0
在Java 中安全使用接口引用
我使用Java 开发过很多项目,这其中包括一些Web 应用和Android 客户端应用。作为Android 开发人员,Java 就像我们的母语一样,但Android 世界是多元化的,并不是只有Java 才能用来写Android 程序,Kotlin 和Groovy 同样优秀,并且有着大量的粉丝。
程序亦非猿
2019/08/16
1.8K0
Modifying namespace in XML document programmatically
Modifying namespace in XML document programmatically static XElement stripNS(XElement root) { re
阿新
2018/04/12
1.4K0
Modifying namespace in XML document programmatically
JS开发引用HTML DOM的location和document对象[通俗易懂]
上一次提到,在报表软件FineReport的JavaScript开发中,可以访问并处理的HTML DOM对象有windows、location、document三种。这次就继续介绍后两种,location和document对象。
全栈程序员站长
2022/09/09
2.1K0
JS开发引用HTML DOM的location和document对象[通俗易懂]
[C++20] Module partitions和符号交叉引用(声明和实现分离)
C++20 开始支持 Module 了。在以前C++为了解决循环依赖问题,经常会把类或者函数声明写前面,实现写后面。然后中间的代码就可以实现内部模块的内聚而互相引用。比如:
owent
2021/03/29
1.7K0
Web安全 | 带你了解一下XML及其注入的相关知识
前段时间学习了.Net,通过更改XML让连接数据库变得更方便,简单易懂,上手无压力,便对XML注入这块挺感兴趣的,刚好学校也开了XML课程,忍不住花时间研究了一下
Power7089
2019/07/25
4K0
Web安全 | 带你了解一下XML及其注入的相关知识
js中获取html元素之document.documentElement
Document.documentElement 是一个会返回文档对象(document)的根元素的只读属性(如HTML文档的 <html> 元素)。
全栈程序员站长
2022/09/09
6.9K0
js中获取html元素之document.documentElement
iOS 在文件中访问 Document Directory
iOS 11之后,在 Plist 中设置LSSupportsOpeningDocumentsInPlace为 YES,且UIFileSharingEnabled为 YES,可以从系统的Files应用中访问应用的 Documents 目录。
莫空9081
2021/08/30
4.2K0
【说站】python中XML删除元素
以上就是python中XML删除元素的方法,希望对大家有所帮助。更多Python学习指路:python基础教程
很酷的站长
2022/11/24
1K0
fastjson 重复引用和循环引用问题
数据传输使用json格式再方便不过了。 fastjson 由阿里巴巴那伙人使用Java语言编写,号称最快的JSON库 前两天遇到一个问题 后台的数据转化为json字符串后发送到前台出现了$ref字样的东西,后来明白了这是引用,在传输的数据中出现相同的对象时,fastjson默认开启引用检测将相同的对象写成引用的形式. 说到引用分为两种,重复引用和循环引用
Mshu
2018/10/31
2.7K0
JavaScript中的document.cookie的使用
我们已经知道,在 document 对象中有一个 cookie 属性。但是 Cookie 又是什么?“某些 Web 站点在您的硬盘上用很小的文本文件存储了一些信息,这些文件就称为 Cookie。”—— MSIE 帮助。一般来说,Cookies 是 CGI 或类似,比 HTML 高级的文件、程序等创建的,但是 javascript 也提供了对 Cookies 的很全面的访问权利。
全栈程序员站长
2022/09/18
1K0
点击加载更多

相似问题

XSLT中的XML交叉引用

21

使用包含XSLT中的引用的document()解析XML

12

在XSLT中交叉引用和条件

10

确定XSLT中“使用”的所有xpath引用/ xml元素

36

在xslt中嵌入和引用xml片段

22
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档