xml - 按属性对 XML 进行排序和修改

标签 xml sorting xslt open-source

<分区>

首先是一些背景知识:我使用馆藏管理软件 GCStar 来管理我的数字图书馆(漫画/漫画/电影,随便你怎么说 - 除了书籍之外,它非常棒)。问题是,它不允许我按多个键对货架进行排序,比如按系列和剧集编号。稍后添加的剧集将始终显示在架子的较低位置,并按系列分组。

我仔细检查了配置,发现它使用的 .gcs 文件只不过是一个 XML(我只是粗略地熟悉)。是这样的:

<?xml version="1.0" encoding="UTF-8"?>
<collection type="GCTVepisodes" items="101" version="1.6.1">
 <information>
  <maxId>101</maxId>
 </information>

 <item
  id="1"
  name="The Vice President Doesn't Say Anything about the Possibility of 
        Him Being the Main Character"
  series="Baccano"
  season="1"
  episode="1"
  ...
 >
  <synopsis>It's 1931 and...</synopsis>
 ...
 </item>
 <item ...

据我所知,该程序将始终按 ID 降序排列(每当我添加一集时它都会增加)。所以我需要对此进行转换:

  1. 按系列、季节、剧集对 XML 进行排序
  2. 相应地更改 id 属性,从 1 到结束(也根据此重置 maxId)
  3. 将其全部写成与另一个 XML 相同的格式。

如何做到这一点(显然不是在这里谈论剪切粘贴代码)? XSLT 可以做所有这些事情吗?我应该研究 Perl 中基于树的解析器吗?这是周末,我在 Linux 机器上,所以在 UNIX 上运行的开源解决方案会很好——Perl 中的东西可能是最好的。我应该阅读哪些内容?

如果我不能在家做,好吧,我总是可以在办公室设计一个小型数据阶段工作,但我非常想要一个更简单的解决方案。

谢谢! :)

最佳答案

maxId(和集合中的项目)值不应更改,因为您没有删除或添加 ID。

如果您想要一个简单的命令行开源 XSLT 转换器,请使用 libxml2/libxslt 中的 XSLTProc。几乎每个标准 Linux 上都可以使用它。 http://xmlsoft.org/XSLT/xsltproc2.html

使用这个命令xsltproc transform.xsl input.xml >output.xml

这是一个解决方案,XSLT 转换样式表,它应该可以工作;-)(我有足够的空闲时间来编写代码)

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

<xsl:output method="xml" encoding="UTF-8" indent="yes"/>

<xsl:strip-space elements="*"/>

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

<!-- remove items, they will be sorted and inserted later -->
<xsl:template match="/collection/item"/>

<!-- remove id -->
<xsl:template match="/collection/item/@id"/>

<xsl:template match="/collection">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <!-- copy and sort item by series, then season, then episode -->
        <xsl:for-each select="item">
            <xsl:sort select="@series" data-type="text"/>
            <xsl:sort select="@season" data-type="number"/>
            <xsl:sort select="@episode" data-type="number"/>
            <xsl:copy>
                <xsl:attribute name="id">
                    <xsl:value-of select="position()"/>
                </xsl:attribute>
                <!-- copy the rest of item -->
                <xsl:apply-templates select="@*|node()"/>
            </xsl:copy>
        </xsl:for-each>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

我用这个简化的数据来测试它:

<?xml version="1.0" encoding="UTF-8"?>
<collection type="GCTVepisodes" items="5" version="1.6.1">
 <information>
  <maxId>5</maxId>
 </information>

 <item
  id="1"
  name="The Vice President Doesn't Say Anything about the Possibility of 
        Him Being the Main Character"
  series="Baccano"
  season="1"
  episode="1"/>

 <item
  id="2"
  name="blabla"
  series="c"
  season="1"
  episode="2"/>

 <item
  id="3"
  name="abc"
  series="Baccano"
  season="2"
  episode="1"/>  

 <item
  id="4"
  name="blabla2"
  series="Baccano"
  season="1"
  episode="2"/>

 <item
  id="5"
  name="first of c"
  series="c"
  season="1"
  episode="1"/>

</collection>

这是结果(看看 position 和 id 是如何变化的):

<?xml version="1.0" encoding="UTF-8"?>
<collection type="GCTVepisodes" items="5" version="1.6.1">
  <information>
    <maxId>5</maxId>
  </information>
  <item id="1" name="The Vice President Doesn't Say Anything about the Possibility of    Him Being the Main Character" series="Baccano" season="1" episode="1"/>
  <item id="2" name="blabla2" series="Baccano" season="1" episode="2"/>
  <item id="3" name="abc" series="Baccano" season="2" episode="1"/>
  <item id="4" name="first of c" series="c" season="1" episode="1"/>
  <item id="5" name="blabla" series="c" season="1" episode="2"/>
</collection>

关于xml - 按属性对 XML 进行排序和修改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6630787/

相关文章:

java - 在 java 中禁用唯一分区属性模式验证

xslt - XSLT和Xpath语法>如何在“外部”范围内引用元素

XSLT 拆分大型单个父节点,分组为较小的子节点

java - 使用 Xerces 忽略奇怪的解析错误

java - 即使pom.xml中存在依赖关系,也无法为org.json.simple.parser.ParseException找到类?

当条目 >= 10 时,javaScript 快速排序不起作用

Java HashMap 先按值再按键排序

xml - XPath 查找元素中最后一个文本节点

java - 错误 StatusLogger 重新配置失败 : No configuration found for '73d16e93' at 'null' in 'null'

javascript - 首先按数字中的给定属性对对象数组进行排序,然后是字母(数字具有子排序)