首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >XSL:如何批量设置空属性?

XSL:如何批量设置空属性?
EN

Stack Overflow用户
提问于 2015-06-27 21:41:17
回答 3查看 210关注 0票数 0

这里是一个XML文件,表示项目及其优先级级别的列表,刻度为1-3。在创建文件时,没有设置优先级级别:

代码语言:javascript
运行
复制
<root>
<section number="1">    
<group number="1.1">
  <item date="today" priority="Undefined"><title>Item1</title></item>
  <item date="today" priority="Undefined"><title>Item2</title></item>
  <item date="yesterday" priority="Undefined"><title>Item3</title></item>
</group>
  <group number="1.2">
    <item date="tomorrow" priority="Undefined"><title>Item4</title></item>
    <item date="today" priority="Undefined"><title>Item5</title></item>
    <item date="yesterday" priority="Undefined"><title>Item5</title></item>
  </group>
</section>
</root>

我后来得到了按项目分列的优先事项清单。他们只是在一个普通的文本文件中找到我,但我可以将它们放入任何必要的格式,包括XML。举个例子:

代码语言:javascript
运行
复制
<priorities>
<item1 p="1">
<item2 p="3">
<item3 p="1">
<item4 p="2">
<item5 p="3">
<item6 p="3">
</priorities>

我试图编写一个XSL转换,为每个项目适当地设置优先级属性。

在我看来,它应该是这样工作的(我已经有了第一步):

  1. 使用身份转换
  2. 创建某种数据结构(“Item1”:“1”,“Item2”:“3”,.)
  3. 创建一个模板,其中:
    • 匹配项元素。
    • 检查标题
    • 在数据结构中查找该标题。
    • 适当地设置优先级级别(我想我知道如何做这部分)

或者,我想了另一种方法:

  1. 使用标识转换(已经写入)
  2. 创建3种数据结构:
    • $P1 := ('Item1','Item2')
    • $P2 := ('Item4')
    • $P3 := (“Item2”、“Item5”、“Item6”)

  1. 创建3个模板,每个优先级级别一个。例如,P1模板:
    • 匹配项元素。
    • 检查标题
    • 检查标题是否为$P1:的成员
      • 如果是,则适当地设置优先级级别。
      • 如果没有,什么也不做

注意:--这是一个精馏的示例;我正在尝试创建一个解决方案,该解决方案可以处理一个包含大约600个项目元素的解决方案,其中包含非常长的字符串作为标题。

我一直在谷歌上搜索,一直在想这样的事情是否可能发生。

用氧气16。

EN

回答 3

Stack Overflow用户

发布于 2015-06-27 22:05:21

你的基本逻辑是正确的。这取决于您的第二个输入(标题到优先级映射)的外观。

假设它本身就是XML,那么您可以将它传递到样式表的<xsl:param>中,并将其用作引用。如果您像这样构建映射文档:

代码语言:javascript
运行
复制
<root>
    <title priority="1">Item1</title>
    <!-- etc -->
</root>

那么XSLT可能如下所示:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8" ?>
<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:output method="xml" encoding="UTF-8" indent="yes" />

    <!-- pass in your mapping nodelist from the host environment -->    
    <xsl:param name="priorityByTitle" />

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>

    <xsl:template match="@priority">
        <xsl:copy-of select="$priorityByTitle//title[. = current()/../title]/@priority" />
    </xsl:template>
</xsl:transform>

许多主机环境允许以某种方式将实际的nodelist对象传递给XSLT处理器的参数。当然,您也可以使用文件和document()

代码语言:javascript
运行
复制
<xsl:variable name="priorityByTitle" select="document('mapping.xml')" />
票数 1
EN

Stack Overflow用户

发布于 2015-06-27 23:54:33

如果您可以将优先级作为XML文档提供,那么我建议使用一个钥匙来查找其中的值--特别是如果您可以使用XSLT2.0,在这里跨文档查找非常简单。

例如,假设XML文档如下:

priorities.xml

代码语言:javascript
运行
复制
<priorities>
    <priority title="Item1">1</priority>
    <priority title="Item2">3</priority>
    <priority title="Item3">1</priority>
    <priority title="Item4">2</priority>
    <priority title="Item5">3</priority>
    <priority title="Item6">3</priority>
</priorities>

以下样式表:

XSLT2.0

代码语言:javascript
运行
复制
<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:key name="priority-by-title" match="priority" use="@title" />
<xsl:param name="path-to-priorities" select="'path/to/priorities.xml'"/>

<!-- identity transform -->
<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template>

<xsl:template match="itemx/@priority">
    <xsl:attribute name="priority">
        <xsl:value-of select="key('priority-by-title', ../title, document($path-to-priorities))" />
    </xsl:attribute>
</xsl:template>

</xsl:stylesheet>

将返回:

代码语言:javascript
运行
复制
<?xml version="1.0" encoding="UTF-8"?>
<root>
   <section number="1">
      <group number="1.1">
         <item date="today" priority="1">
            <title>Item1</title>
         </item>
         <item date="today" priority="3">
            <title>Item2</title>
         </item>
         <item date="yesterday" priority="1">
            <title>Item3</title>
         </item>
      </group>
      <group number="1.2">
         <item date="tomorrow" priority="2">
            <title>Item4</title>
         </item>
         <item date="today" priority="3">
            <title>Item5</title>
         </item>
         <item date="yesterday" priority="3">
            <title>Item5</title>
         </item>
      </group>
   </section>
</root>

注意,XML是区分大小写的:item1Item1不匹配。

若要仅对优先级文件中具有匹配项的项进行查找,可以使用:

代码语言:javascript
运行
复制
<xsl:template match="item[key('priority-by-title', title, document($path-to-priorities))]/@priority">
    <xsl:attribute name="priority">
        <xsl:value-of select="key('priority-by-title', ../title, document($path-to-priorities))" />
    </xsl:attribute>
</xsl:template>
票数 1
EN

Stack Overflow用户

发布于 2015-06-27 23:09:23

若要将主输入中未定义的n‘the替换为优先级文件中n’the项的优先级,请使用

代码语言:javascript
运行
复制
<xsl:template match="@priority[.='Undefined']">
  <xsl:variable name="pos" select="count(../preceding::*[@priority='Undefined']"/>
  <xsl:attribute name="priority" select="(doc('priorities.xml')//priority)[$pos]"/>
</xsl:template>

结合一个合适的身份模板。

那是O(n^2),如果不是星期六晚上的午夜,我相信你会做得更好的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31093804

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档