当前位置: 首页 > 知识库问答 >
问题:

将XML节点对半(XSLT转换)

高海阳
2023-03-14

您能帮助如何用子节点分割成半节点吗?

输入:

<RuleCollection Type="Exe" EnforcementMode="Enabled">
 <FileHashRule Id="1">
  <Conditions>
   <FileHashCondition>
    <FileHash Type="SHA256" Data="0xCC864"></FileHash>
    <FileHash Type="SHA256" Data="0x9D973"></FileHash>
    <FileHash Type="SHA256" Data="0xA92EF"></FileHash>
    <FileHash Type="SHA256" Data="0x279CD"></FileHash>
   </FileHashCondition>
  </Conditions>
 </FileHashRule>
</RuleCollection>

输出:

<RuleCollection Type="Exe" EnforcementMode="Enabled">
 <FileHashRule Id="hard-coded guid1">
  <Conditions>
   <FileHashCondition>
    <FileHash Type="SHA256" Data="0xCC864"></FileHash>
    <FileHash Type="SHA256" Data="0x9D973"></FileHash>
   </FileHashCondition>
  </Conditions>
 </FileHashRule>
 <FileHashRule Id="hard-coded guid2">
  <Conditions>
   <FileHashCondition>
    <FileHash Type="SHA256" Data="0xA92EF"></FileHash>
    <FileHash Type="SHA256" Data="0x279CD"></FileHash>
   </FileHashCondition>
  </Conditions>
 </FileHashRule>
</RuleCollection>

不幸的是,我对xslt没有经验,也没有找到这样的例子。

更新后,我尝试了下面建议的方法之一,并有这个https://xsltfiddle.liberty-development.net/jyH9rNq/3节点不复制

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" indent="yes"/>

        <xsl:variable name="fileHash" select="/FileHashRule/Conditions/FileHashCondition/FileHash" />
        <xsl:variable name="half" select="count($fileHash) div 2" />

        <xsl:template match="/">
        <RuleCollection>
            <FileHashRule>
                <xsl:attribute name="Id">ad22d301-eb88-485d-ae1d-537790bdebfa</xsl:attribute>
                    <Conditions>

                        <FileHashCondition>
                        <xsl:copy-of select="$fileHash[position() &lt;= $half]" />

                        </FileHashCondition>
                    </Conditions>
            </FileHashRule>

                <FileHashRule>
                <xsl:attribute name="Id">ad22d301-eb88-485d-ae1d-537790bdebfb</xsl:attribute>
                    <Conditions>

                        <FileHashCondition>
                        <xsl:copy-of select="$fileHash[position() &gt; $half]" />
                        </FileHashCondition>
                    </Conditions>
            </FileHashRule>


        </RuleCollection>
        </xsl:template>

        </xsl:stylesheet>   

输出:

        <?xml version="1.0" encoding="UTF-8"?>
    <RuleCollection>
       <FileHashRule Id="ad22d301-eb88-485d-ae1d-537790bdebfa">
          <Conditions>
             <FileHashCondition/>
          </Conditions>
       </FileHashRule>
       <FileHashRule Id="ad22d301-eb88-485d-ae1d-537790bdebfb">
          <Conditions>
             <FileHashCondition/>
          </Conditions>
       </FileHashRule>
    </RuleCollection>

共有3个答案

姬和豫
2023-03-14

这里有一种方法

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

<xsl:template match="FileHashRule">
  <FileHashRule Id="{@Id}">
    <xsl:apply-templates mode="one"/>
  </FileHashRule>
  <FileHashRule Id="{@Id + 1}">
    <xsl:apply-templates mode="two"/>
  </FileHashRule>
</xsl:template>

<xsl:template match="FileHash[position() > last() div 2]" mode="one"/>
<xsl:template match="FileHash[position() &lt;= last() div 2]" mode="two"/>

第一条规则是:默认情况下,复制节点不变。

第二条规则说:对于FileHash规则,创建两个副本,在第二个副本中增加@Id属性。

第三条规则是:在第一阶段,跳过列表后半部分中的任何FileHash元素。

第四条规则说:在第二阶段,跳过列表前半部分的任何FileHash元素。

陶博耘
2023-03-14

你可以很简单地通过以下方式找到半个点:

<xsl:variable name="fileHash" select="/RuleCollection/FileHashRule/Conditions/FileHashCondition/FileHash" />
<xsl:variable name="half" select="count($fileHash) div 2" />

然后只需创建两个FileHash规则元素并使用:

<xsl:copy-of select="$fileHash[position() &lt;= $half]" />

填充第一个,并且:

<xsl:copy-of select="$fileHash[position() &gt; $half]" />

对于第二个。

令狐高洁
2023-03-14

您可以从(XSLT Fiddle)这样的内容开始:

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

  <xsl:template match="//xs">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select='x[position() &lt;= last() div 2]'/>
    </xsl:copy>

    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select='x[position() &gt; last() div 2]'/>
    </xsl:copy>
  </xsl:template>

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

</xsl:stylesheet>

它会分裂

<?xml version="1.0" encoding="utf-8" ?>
<data>
    <xs a="b">
        <will-not-be-copied/>
        <x>1</x>
        <x>2</x>
        <x>3</x>
        <x>4</x>
    </xs>
</data>

进入

<?xml version="1.0" encoding="UTF-8"?>
<data>
    <xs a="b">
      <x>1</x>
      <x>2</x>
   </xs>
   <xs a="b">
      <x>3</x>
      <x>4</x>
   </xs>
</data>

不过请注意,您需要澄清如何处理

 类似资料:
  • 我有一个XML文件: 我想使用XSLT将其转换为have: 我的文件: 但是我的输出文件中没有根节点。如何做到这一点? 还有,这是一个好的方法来进行转换吗?堆叠几个模板?

  • XML输入文件: XML输入文件转换为XML输出文件。将XML输入文件的firstName、middleName和lastName标签合并为XML Ouput文件的name标签,将XML输入文件的address1、address2、city、state和pincode标签合并为XML Ouput文件的address标签。 我几乎转换了代码,但我在这里与empId作斗争。我已经在XSLT文件中手动输

  • 我是XSLT新手。我想根据其他子节点的条件更改XML中的根节点。但子节点始终保持不变。例如,我有以下XML: 我喜欢将XML更改为: 这意味着依赖于<代码> 我不想在每个<代码>

  • 我想从XML结构中使用单个节点创建嵌套的XML节点,我尝试过但无法带来嵌套的XML结构,请一些人帮助我,我无法获得预期的行为。 XML结构: XSL使用: 收到的输出: 预期产出 “人员非活动”元素应用于匹配

  • 我有一个XML: 我想向根元素:/doc添加一个属性(名称空间),以便输出如下所示: 我尝试了三种xslt(跳过了默认的“复制所有”部分以减少问题的长度)。 xslt1:见下文,问题在于将空名称空间xmlns=”“添加到/doc的所有子节点(即:/doc/tag1和/doc/tag2) Xslt2:见下文,问题是“ns”被添加到根节点:和 xslt3:请参见下文,问题是报告了错误:未定义名称空间前

  • 我有以下问题。我不是XSLT方面最伟大的专家,我想成功的是将一个XML从赛贝斯转换为以下内容: Sybase的输出: 我希望它的输出标题保持原样,条目部分不同 这是到目前为止我的XSLT(对不起,不太可能) 也许,有人可以帮我实现我想要的。非常感谢你。