我觉得这个问题很简单,但我已经好几年没有做过任何 xslt 了,所以也许有人可以提供帮助?
我有一段由 .net 类 DataContractSerializer 生成的 xml,我需要使用 xslt 从这个 xml 中提取数据以得到一些 html。对我来说让事情变得复杂的是命名空间的大量使用......
xml 的片段如下所示:
<FundDeal xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Deal">
<Id xmlns="http://schemas.datacontract.org/2004/07/Guide.BusinessObjects.Deal">DEAL12345</Id>
<Account xmlns:d2p1="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Account">
<d2p1:AlternateId i:nil="true"/>
<d2p1:Designation>XXX</d2p1:Designation>
<d2p1:Name>QWERTY</d2p1:Name>
<d2p1:Number>12345678</d2p1:Number>
<d2p1:Status i:nil="true"/>
</Account>
<Agent xmlns:d2p1="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Account">
<d2p1:Id>54321</d2p1:Id>
<d2p1:Name>ASDFG</d2p1:Name>
<d2p1:Status>Active</d2p1:Status>
</Agent>
....
</FundDeal>
现在,我需要通过一个样式表来转换这个 xml,我发现这个过程非常艰难。我认识到 xsl 需要它自己对所涉及的命名空间的引用,并且可以使用以下 xsl 轻松提取上面的 Deal Id 之类的内容:
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ms="urn:schemas-microsoft-com:xslt"
xmlns:grbd="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Deal"
xmlns:gbd="http://schemas.datacontract.org/2004/07/Guide.BusinessObjects.Deal"
xmlns:grba="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Account">
<xsl:output indent="yes" omit-xml-declaration="yes" method="html"/>
<xsl:template match="/">
<html>
<head>
<!-- some styles here -->
</head>
<body>
<table cellpadding="5" cellspacing="5" border="0">
<tr>
<td class="SectionTitle" colspan="2">
<xsl:text>Deal Cancellation Notification - </xsl:text>
<xsl:value-of select="//ggbd:Id"/>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
但我很难读取诸如帐户名称之类的内容,因为似乎有多个 namespace 在运行。
谁能告诉我访问 (a) 帐户名和 (b) 代理名的 xpath?我认为了解如何访问这些可能会让我访问我需要的所有其他内容。
非常感谢, 皮特
最佳答案
如果您打算使用 XML,那么值得深入了解命名空间——尽管这可能会很痛苦。从长远来看,推迟你的理解只会让事情变得更加痛苦。
帐户名称或代理名称没有“多个 namespace ”:一个元素最多只出现在一个 namespace 中。
您看到的大多数命名空间语法只是将命名空间前缀绑定(bind)到命名空间名称 (URI)。所以当你看到
xmlns:i="http://www.w3.org/2001/XMLSchema-instance"
this is binding the prefix "i" to the URI "http://www.w3.org/2001/XMLSchema-instance", so that deeper elements in the document might use the "i" prefix (essentially as a way of saving keystrokes).
When the xmlns attribute is specified on its own with a value (i.e. you see xmlns="something"), this means that Namespace is an effect for this element and its descendants (unless overridden by a another Namespace being specified at a deeper level).
Thus, in your example document (which is a bit of a Namespace hodge-podge) the Namespace Name of the root FundDeal element is "http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Deal", and this is also the case for its child Account and Agent elements (although they happen to define a namespace/prefix binding this does not affect their own Namespace: this binding is used by their child elements).
You can specify the Namespaces in your stylesheet most easily by binding you own prefixes ("fund" and "deal" in the example below) to refer to Namespaces you need (I have added a bit more which I hope makes it a bit clearer):
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fund="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Deal"
xmlns:deal="http://schemas.datacontract.org/2004/07/Guide.BusinessObjects.Deal"
xmlns:d2p1="http://schemas.datacontract.org/2004/07/Guide.Rx.BusinessObjects.Account">
<xsl:output indent="yes" omit-xml-declaration="yes" method="html"/>
<xsl:template match="/">
<html>
<head>
<!-- some styles here -->
</head>
<body>
<table cellpadding="5" cellspacing="5" border="0">
<tr>
<td class="SectionTitle" colspan="2">
<xsl:text>Deal Cancellation Notification - </xsl:text>
<xsl:value-of select="/fund:FundDeal/deal:Id"/>
<br/>
<xsl:text>Account Name - </xsl:text>
<xsl:value-of select="/fund:FundDeal/fund:Account/d2p1:Name"/>
<br/>
<xsl:text>Agent Name - </xsl:text>
<xsl:value-of select="/fund:FundDeal/fund:Agent/d2p1:Name"/>
</td>
</tr>
</table>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
关于xml - 如何处理 XML 命名空间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6188689/
我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
当我在我的Rails应用程序根目录中运行rakedoc:app时,API文档是使用/doc/README_FOR_APP作为主页生成的。我想向该文件添加.rdoc扩展名,以便它在GitHub上正确呈现。更好的是,我想将它移动到应用程序根目录(/README.rdoc)。有没有办法通过修改包含的rake/rdoctask任务在我的Rakefile中执行此操作?是否有某个地方可以查找可以修改的主页文件的名称?还是我必须编写一个新的Rake任务?额外的问题:Rails应用程序的两个单独文件/README和/doc/README_FOR_APP背后的逻辑是什么?为什么不只有一个?
我没有找到太多关于如何执行此操作的信息,尽管有很多关于如何使用像这样的redirect_to将参数传递给重定向的建议:action=>'something',:controller=>'something'在我的应用程序中,我在路由文件中有以下内容match'profile'=>'User#show'我的表演Action是这样的defshow@user=User.find(params[:user])@title=@user.first_nameend重定向发生在同一个用户Controller中,就像这样defregister@title="Registration"@user=Use
我们目前正在为ROR3.2开发自定义cms引擎。在这个过程中,我们希望成为我们的rails应用程序中的一等公民的几个类类型起源,这意味着它们应该驻留在应用程序的app文件夹下,它是插件。目前我们有以下类型:数据源数据类型查看我在app文件夹下创建了多个目录来保存这些:应用/数据源应用/数据类型应用/View更多类型将随之而来,我有点担心应用程序文件夹被这么多目录污染。因此,我想将它们移动到一个子目录/模块中,该子目录/模块包含cms定义的所有类型。所有类都应位于MyCms命名空间内,目录布局应如下所示:应用程序/my_cms/data_source应用程序/my_cms/data_ty
Rails中有没有一种方法可以提取与路由关联的HTTP动词?例如,给定这样的路线:将“users”匹配到:“users#show”,通过:[:get,:post]我能实现这样的目标吗?users_path.respond_to?(:get)(显然#respond_to不是正确的方法)我最接近的是通过执行以下操作,但它似乎并不令人满意。Rails.application.routes.routes.named_routes["users"].constraints[:request_method]#=>/^GET$/对于上下文,我有一个设置cookie然后执行redirect_to:ba
我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?
假设您编写了一个类Sup,我决定将其扩展为SubSup。我不仅需要了解你发布的接口(interface),还需要了解你的私有(private)字段。见证这次失败:classSupdefinitialize@privateField="fromsup"enddefgetXreturn@privateFieldendendclassSub问题是,解决这个问题的正确方法是什么?看起来子类应该能够使用它想要的任何字段而不会弄乱父类(superclass)。编辑:equivalentexampleinJava返回"fromSup",这也是它应该产生的答案。 最佳答案
我在尝试使用Nokogiri构建XML文档时遇到了一个小问题。我想将我的元素之一称为“文本”(请参阅下面粘贴代码的最底部)。通常,要创建一个新元素,我会执行类似以下的操作xml.text--但它似乎是.text是Nokogiri已经用来做其他事情的方法。因此,当我写这行时xml.textNokogiri没有创建名为的新元素但只是写了意味着成为元素内容的文本。我怎样才能让Nokogiri实际制作一个名为的元素??builder=Nokogiri::XML::Builder.newdo|xml|xml.TEI("xmlns"=>"http://www.tei-c.org/ns/1.0"
我在一个简单的RailsAPI中有以下Controller代码:classApi::V1::AccountsControllerehead:not_foundendendend问题在于,生成的json具有以下格式:{id:2,name:'Simpleaccount',cash_flows:[{id:1,amount:34.3,description:'simpledescription'},{id:2,amount:1.12,description:'otherdescription'}]}我需要我生成的json是camelCase('cashFlows'而不是'cash_flows'