草庐IT

xml - XSLT 处理元素的第一次出现

coder 2024-07-01 原文

我必须采用 XML 数据提要并将其转换为 json,扁平化以便我没有 json 对象。我有一些工作,除了多次出现的元素,我得到多次出现。我明白为什么 apply-templates 命令会发生这种情况,我只是不确定如何修复它。

原始 XML 如下所示:

<entry>
  <id>542345255</id>
  <published>2013-10-15T15:30:02Z</published>
  <link rel="alternate" type="text/html" href="http://test.com"/>
  <link rel="self" type="application/json" href="http://test1.com"/>
</entry>

期望的结果是:

{
  "id" : "542345255",
  "published" : "2013-10-15T15:30:02Z",
  "link_rel" : "[alternate, self]",
  "link_type" : "[text/html, application/json]",
  "link_href" : "[http://test.com, http://test1.com]"
}

我的 XSLT 是:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="utf-8"/>

<xsl:variable name="links" select="entry/link"/>

<xsl:template match="entry">
  <xsl:text>{</xsl:text>
  <xsl:apply-templates/>
  <xsl:text>}</xsl:text>
</xsl:template>

<xsl:template match="id">
  <xsl:text>"id" : "</xsl:text>
  <xsl:value-of select="."/>
  <xsl:text>", </xsl:text>
</xsl:template>

<xsl:template match="published">
  <xsl:text>"postedTime" : "</xsl:text>
  <xsl:value-of select="."/>
  <xsl:text>", </xsl:text>
 </xsl:template>

 <xsl:template match="link">

   <xsl:text>"link_rel" : "[</xsl:text>
   <xsl:for-each select="$links">
     <xsl:value-of select="./@rel"/>
     <xsl:if test="position()!=last()">, </xsl:if>
   </xsl:for-each>
   <xsl:text>]", </xsl:text>

   <xsl:text>"link_type" : "[</xsl:text>
   <xsl:for-each select="$links">
     <xsl:value-of select="./@type"/>
     <xsl:if test="position()!=last()">, </xsl:if>
    </xsl:for-each>
    <xsl:text>]", </xsl:text>

    <xsl:text>"link_href" : "[</xsl:text>
    <xsl:for-each select="$links">
      <xsl:value-of select="./@href"/>
      <xsl:if test="position()!=last()">, </xsl:if>
    </xsl:for-each>
    <xsl:text>]", </xsl:text>

  </xsl:template>
</xsl:stylesheet>

有了这个,我得到的结果是:

{
  "id" : "542345255",
  "published" : "2013-10-15T15:30:02Z",
  "link_rel" : "[alternate, self]",
  "link_type" : "[text/html, application/json]",
  "link_href" : "[http://test.com, http://test1.com]"
  "link_rel" : "[alternate, self]",
  "link_type" : "[text/html, application/json]",
  "link_href" : "[http://test.com, http://test1.com]"
}

最佳答案

您可以使用 xsl:for-each-group 做一些更通用的事情。 (您的示例 XSLT 是 2.0。)

例子...

XML 输入

<entry>
    <id>542345255</id>
    <published>2013-10-15T15:30:02Z</published>
    <link rel="alternate" type="text/html" href="http://test.com"/>
    <link rel="self" type="application/json" href="http://test1.com"/>
</entry>

XSLT 2.0

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output method="text"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="/*">
        <xsl:text>{&#xA;</xsl:text>
        <xsl:for-each-group select="*[text()]" group-by="name()">
            <xsl:call-template name="json">
                <xsl:with-param name="name" select="name()"/>
            </xsl:call-template>
        </xsl:for-each-group>
        <xsl:for-each-group select="*/@*" group-by="concat(../name(),name())">
            <xsl:call-template name="json">
                <xsl:with-param name="name" select="concat(../name(),'_',name())"/>
            </xsl:call-template>
        </xsl:for-each-group>
        <xsl:text>}</xsl:text>
    </xsl:template>

    <xsl:template match="*[text()]" mode="json">
        <xsl:value-of select="concat('&quot;',name(),'&quot;',' : &quot;',.,'&quot;&#xA;')"/>
    </xsl:template>

    <xsl:template name="json">
        <xsl:param name="name"/>
        <xsl:value-of select="concat('&#x9;&quot;',$name,'&quot;',' : &quot;')"/>
        <xsl:if test="count(current-group())>1">
            <xsl:text>[</xsl:text>
        </xsl:if>
        <xsl:value-of select="current-group()" separator=", "/>
        <xsl:if test="count(current-group())>1">
            <xsl:text>]</xsl:text>
        </xsl:if>
        <xsl:text>&quot;</xsl:text>
        <xsl:if test="(self::* and (//@*)[1]) or not(last()=position())">
            <xsl:text>,</xsl:text>
        </xsl:if>
        <xsl:text>&#xA;</xsl:text>                  
    </xsl:template>

</xsl:stylesheet>

输出

{
    "id" : "542345255",
    "published" : "2013-10-15T15:30:02Z",
    "link_rel" : "[alternate, self]",
    "link_type" : "[text/html, application/json]",
    "link_href" : "[http://test.com, http://test1.com]"
}

关于xml - XSLT 处理元素的第一次出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19436042/

有关xml - XSLT 处理元素的第一次出现的更多相关文章

  1. ruby - 如何指定 Rack 处理程序 - 2

    Rackup通过Rack的默认处理程序成功运行任何Rack应用程序。例如:classRackAppdefcall(environment)['200',{'Content-Type'=>'text/html'},["Helloworld"]]endendrunRackApp.new但是当最后一行更改为使用Rack的内置CGI处理程序时,rackup给出“NoMethodErrorat/undefinedmethod`call'fornil:NilClass”:Rack::Handler::CGI.runRackApp.newRack的其他内置处理程序也提出了同样的反对意见。例如Rack

  2. ruby - 使用 Vim Rails,您可以创建一个新的迁移文件并一次性打开它吗? - 2

    使用带有Rails插件的vim,您可以创建一个迁移文件,然后一次性打开该文件吗?textmate也可以这样吗? 最佳答案 你可以使用rails.vim然后做类似的事情::Rgeneratemigratonadd_foo_to_bar插件将打开迁移生成的文件,这正是您想要的。我不能代表textmate。 关于ruby-使用VimRails,您可以创建一个新的迁移文件并一次性打开它吗?,我们在StackOverflow上找到一个类似的问题: https://sta

  3. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

    在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

  4. ruby-on-rails - 如何从 format.xml 中删除 <hash></hash> - 2

    我有一个对象has_many应呈现为xml的子对象。这不是问题。我的问题是我创建了一个Hash包含此数据,就像解析器需要它一样。但是rails自动将整个文件包含在.........我需要摆脱type="array"和我该如何处理?我没有在文档中找到任何内容。 最佳答案 我遇到了同样的问题;这是我的XML:我在用这个:entries.to_xml将散列数据转换为XML,但这会将条目的数据包装到中所以我修改了:entries.to_xml(root:"Contacts")但这仍然将转换后的XML包装在“联系人”中,将我的XML代码修改为

  5. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  6. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  7. ruby-on-rails - Rake 任务仅调用一次时执行两次 - 2

    我写了一个非常简单的rake任务来尝试找到这个问题的根源。namespace:foodotaskbar::environmentdoputs'RUNNING'endend当在控制台中执行rakefoo:bar时,输出为:RUNNINGRUNNING当我执行任何rake任务时会发生这种情况。有没有人遇到过这样的事情?编辑上面的rake任务就是写在那个.rake文件中的所有内容。这是当前正在使用的Rakefile。requireFile.expand_path('../config/application',__FILE__)OurApp::Application.load_tasks这里

  8. ruby - 使用 rbenv 和 ruby​​-build 构建 ruby​​ 失败,出现 undefined symbol : SSLv2_method - 2

    我正在尝试在配备ARMv7处理器的SynologyDS215j上安装ruby​​2.2.4或2.3.0。我用了optware-ng安装gcc、make、openssl、openssl-dev和zlib。我根据README中的说明安装了rbenv(版本1.0.0-19-g29b4da7)和ruby​​-build插件。.这些是随optware-ng安装的软件包及其版本binutils-2.25.1-1gcc-5.3.0-6gconv-modules-2.21-3glibc-opt-2.21-4libc-dev-2.21-1libgmp-6.0.0a-1libmpc-1.0.2-1libm

  9. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

  10. ruby - 我怎样才能只写一次 "Text"并同时检查 path_info 是否包含 'A' ? - 2

    -if!request.path_info.include?'A'%{:id=>'A'}"Text"-else"Text"“文本”写了两次。我怎样才能只写一次并同时检查path_info是否包含“A”? 最佳答案 有两种方法可以做到这一点。使用部分,或使用content_forblock:如果“文本”较长,或者是一个重要的子树,您可以将其提取到一个部分。这会使您的代码变干一点。在给出的示例中,这似乎有点矫枉过正。在这种情况下更好的方法是使用content_forblock,如下所示:-if!request.path_info.inc

随机推荐