【问题标题】:Need help removing text and replacing xlm via XLST需要帮助通过 XSLT 删除文本和替换 xml
【发布时间】:2012-07-13 17:01:47
【问题描述】:

我完全被困住了。我正在尝试使用 XLST 来查找/替换部分 xml 输出文件。我真的连起点都没有。我曾尝试使用 Altova DiffDog 自动生成我的 xlst,因为我自己并没有牢牢掌握如何编写它。

这是我当前的 xml 输出文件:

<?xml version='1.0' encoding='UTF-8'?>
<BB:Report_Data xmlns:BB="urn:com.playdate.report/Report-Outbound">
   <BB:Report_Entry>
      <BB:leaveBalanceTotal.employeeId>1234567</BB:leaveBalanceTotal.employeeId>
      <BB:leaveBalanceTotal.bmbId>9280136270</BB:leaveBalanceTotal.bmbId>
      <BB:All_Eligible_Time_Off_Plans_for_Worker>
         <BB:leaveBalanceTotal.leaveCodeId>1010</BB:leaveBalanceTotal.leaveCodeId>
         <BB:leaveBalanceTotal.balanceAmount>0</BB:leaveBalanceTotal.balanceAmount>
         <BB:leaveBalanceTotal.effectiveDate>2012-07-05</BB:leaveBalanceTotal.effectiveDate>
         <BB:leaveBalanceTotal.lastPayEndDate>2012-07-05</BB:leaveBalanceTotal.lastPayEndDate>
      </BB:All_Eligible_Time_Off_Plans_for_Worker>
      <BB:All_Eligible_Time_Off_Plans_for_Worker>
         <BB:leaveBalanceTotal.leaveCodeId>1014</BB:leaveBalanceTotal.leaveCodeId>
         <BB:leaveBalanceTotal.balanceAmount>96</BB:leaveBalanceTotal.balanceAmount>
         <BB:leaveBalanceTotal.effectiveDate>2012-07-05</BB:leaveBalanceTotal.effectiveDate>
         <BB:leaveBalanceTotal.lastPayEndDate>2012-07-05</BB:leaveBalanceTotal.lastPayEndDate>
      </BB:All_Eligible_Time_Off_Plans_for_Worker>
      <BB:leaveBalanceTotal.totalDaysService>1459</BB:leaveBalanceTotal.totalDaysService>
   </BB:Report_Entry>
</BB:Report_Data>

这是我需要的样子:

<?xml version='1.0' encoding='UTF-8'?>
<BB:Report_Data xmlns:BB="urn:com.playdate.report/Report-Outbound">
   <leaveBalanceTotal>
      <leaveBalanceTotal.employeeId>1234567</leaveBalanceTotal.employeeId>
      <leaveBalanceTotal.bmbId>9280136270</leaveBalanceTotal.bmbId>
      <leaveBalanceTotal.leaveCodeId>1010</leaveBalanceTotal.leaveCodeId>
      <leaveBalanceTotal.balanceAmount>0</leaveBalanceTotal.balanceAmount>
      <leaveBalanceTotal.effectiveDate>2012-07-05</leaveBalanceTotal.effectiveDate>
      <leaveBalanceTotal.lastPayEndDate>2012-07-05</leaveBalanceTotal.lastPayEndDate>
      <leaveBalanceTotal.leaveCodeId>1014</leaveBalanceTotal.leaveCodeId>
      <leaveBalanceTotal.balanceAmount>96</leaveBalanceTotal.balanceAmount>
      <leaveBalanceTotal.effectiveDate>2012-07-05</leaveBalanceTotal.effectiveDate>
      <leaveBalanceTotal.lastPayEndDate>2012-07-05</leaveBalanceTotal.lastPayEndDate>
      <leaveBalanceTotal.totalDaysService>1459</leaveBalanceTotal.totalDaysService>
   </leaveBalanceTotal>
</BB:Report_Data>

基本上我正在尝试删除所有出现的以下内容:

  1. BB:All_Eligible_Time_Off_Plans_for_Worker
  2. /BB:All_Eligible_Time_Off_Plans_for_Worker
  3. BB:

我需要将 Report_Entry 替换为 leaveBalanceTotal。

任何帮助将不胜感激!

【问题讨论】:

    标签: xml xslt xslt-1.0


    【解决方案1】:

    这是另一个 XSLT 1.0 选项。这也将保留数据可能具有的任何属性。

    XSLT 1.0

    <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
        xmlns:BB="urn:com.playdate.report/Report-Outbound" 
        exclude-result-prefixes="BB">
        <xsl:output indent="yes"/>
        <xsl:strip-space elements="*"/>
    
        <xsl:template match="comment()|processing-instruction()|@*">
            <xsl:copy/>
        </xsl:template>
    
        <xsl:template match="*">
            <xsl:element name="{local-name()}">
                <xsl:apply-templates select="node()|@*"/>
            </xsl:element>
        </xsl:template>
    
        <xsl:template match="BB:All_Eligible_Time_Off_Plans_for_Worker">
            <xsl:apply-templates/>
        </xsl:template>
    
        <xsl:template match="BB:Report_Data">
            <xsl:copy>
                <xsl:apply-templates select="node()|@*"/>
            </xsl:copy>
        </xsl:template>
    
        <xsl:template match="BB:Report_Entry">
            <leaveBalanceTotal>
                <xsl:apply-templates select="node()|@*"/>
            </leaveBalanceTotal>
        </xsl:template>
    
    </xsl:stylesheet>
    

    输出

    <BB:Report_Data xmlns:BB="urn:com.playdate.report/Report-Outbound">
       <leaveBalanceTotal>
          <leaveBalanceTotal.employeeId>1234567</leaveBalanceTotal.employeeId>
          <leaveBalanceTotal.bmbId>9280136270</leaveBalanceTotal.bmbId>
          <leaveBalanceTotal.leaveCodeId>1010</leaveBalanceTotal.leaveCodeId>
          <leaveBalanceTotal.balanceAmount>0</leaveBalanceTotal.balanceAmount>
          <leaveBalanceTotal.effectiveDate>2012-07-05</leaveBalanceTotal.effectiveDate>
          <leaveBalanceTotal.lastPayEndDate>2012-07-05</leaveBalanceTotal.lastPayEndDate>
          <leaveBalanceTotal.leaveCodeId>1014</leaveBalanceTotal.leaveCodeId>
          <leaveBalanceTotal.balanceAmount>96</leaveBalanceTotal.balanceAmount>
          <leaveBalanceTotal.effectiveDate>2012-07-05</leaveBalanceTotal.effectiveDate>
          <leaveBalanceTotal.lastPayEndDate>2012-07-05</leaveBalanceTotal.lastPayEndDate>
          <leaveBalanceTotal.totalDaysService>1459</leaveBalanceTotal.totalDaysService>
       </leaveBalanceTotal>
    </BB:Report_Data>
    

    【讨论】:

    • 第一个模板下的 xsl:apply-templates 是无意义的浪费。这些节点类型永远不能有子节点。
    • @DevNull:cmets 和 PI“确实有孩子”的说法是完全错误的。唯一可以有子节点的两种节点类型是元素节点和文档节点。
    • @DimitreNovaatchev - 是的,你和 SeanB.Durkin 是正确的。不知道我当时在想什么。我要删除评论。
    • @SeanB.Durkin - 删除了 xsl:apply-templates 的无意义浪费。
    【解决方案2】:

    当这个 XSLT:

    <?xml version="1.0" encoding="UTF-8"?>
    <xsl:stylesheet 
      xmlns:BB="urn:com.playdate.report/Report-Outbound"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      version="1.0">
      <xsl:output omit-xml-declaration="no" indent="yes"/>
      <xsl:strip-space elements="*"/>
    
      <!-- Identity Template: copies everything as-is -->
      <xsl:template match="node()|@*">
        <xsl:copy>
          <xsl:apply-templates select="node()|@*"/>
        </xsl:copy>
      </xsl:template>
    
      <!-- Remove BB:All_Eligible_Time_Off_Plans_for_Worker elements -->
      <!-- right away, but process their children -->
      <xsl:template match="BB:All_Eligible_Time_Off_Plans_for_Worker" priority="2">
        <xsl:apply-templates /> 
      </xsl:template>
    
      <!-- Replace BB:Report_Entry elements with leaveBalanceTotal ones -->
      <xsl:template match="BB:Report_Entry">
        <leaveBalanceTotal>
          <xsl:apply-templates />   
        </leaveBalanceTotal>    
      </xsl:template>
    
      <!-- Remove BB namespace from descendent elements -->
      <xsl:template match="BB:Report_Entry/* | 
          BB:All_Eligible_Time_Off_Plans_for_Worker/*">
        <xsl:element name="{local-name(.)}">
          <xsl:apply-templates />   
        </xsl:element>  
      </xsl:template>
    
    </xsl:stylesheet>
    

    ...应用于提供的 XML:

    <?xml version="1.0" encoding="UTF-8"?>
    <BB:Report_Data xmlns:BB="urn:com.playdate.report/Report-Outbound">
      <BB:Report_Entry>
        <BB:leaveBalanceTotal.employeeId>1234567</BB:leaveBalanceTotal.employeeId>
        <BB:leaveBalanceTotal.bmbId>9280136270</BB:leaveBalanceTotal.bmbId>
        <BB:All_Eligible_Time_Off_Plans_for_Worker>
          <BB:leaveBalanceTotal.leaveCodeId>1010</BB:leaveBalanceTotal.leaveCodeId>
          <BB:leaveBalanceTotal.balanceAmount>0</BB:leaveBalanceTotal.balanceAmount>
          <BB:leaveBalanceTotal.effectiveDate>2012-07-05</BB:leaveBalanceTotal.effectiveDate>
          <BB:leaveBalanceTotal.lastPayEndDate>2012-07-05</BB:leaveBalanceTotal.lastPayEndDate>
        </BB:All_Eligible_Time_Off_Plans_for_Worker>
        <BB:All_Eligible_Time_Off_Plans_for_Worker>
          <BB:leaveBalanceTotal.leaveCodeId>1014</BB:leaveBalanceTotal.leaveCodeId>
          <BB:leaveBalanceTotal.balanceAmount>96</BB:leaveBalanceTotal.balanceAmount>
          <BB:leaveBalanceTotal.effectiveDate>2012-07-05</BB:leaveBalanceTotal.effectiveDate>
          <BB:leaveBalanceTotal.lastPayEndDate>2012-07-05</BB:leaveBalanceTotal.lastPayEndDate>
        </BB:All_Eligible_Time_Off_Plans_for_Worker>
        <BB:leaveBalanceTotal.totalDaysService>1459</BB:leaveBalanceTotal.totalDaysService>
      </BB:Report_Entry>
    </BB:Report_Data>
    

    ...产生了预期的结果:

    <?xml version="1.0" encoding="UTF-8"?>
    <BB:Report_Data xmlns:BB="urn:com.playdate.report/Report-Outbound">
      <leaveBalanceTotal>
        <leaveBalanceTotal.employeeId>1234567</leaveBalanceTotal.employeeId>
        <leaveBalanceTotal.bmbId>9280136270</leaveBalanceTotal.bmbId>
        <leaveBalanceTotal.leaveCodeId>1010</leaveBalanceTotal.leaveCodeId>
        <leaveBalanceTotal.balanceAmount>0</leaveBalanceTotal.balanceAmount>
        <leaveBalanceTotal.effectiveDate>2012-07-05</leaveBalanceTotal.effectiveDate>
        <leaveBalanceTotal.lastPayEndDate>2012-07-05</leaveBalanceTotal.lastPayEndDate>
        <leaveBalanceTotal.leaveCodeId>1014</leaveBalanceTotal.leaveCodeId>
        <leaveBalanceTotal.balanceAmount>96</leaveBalanceTotal.balanceAmount>
        <leaveBalanceTotal.effectiveDate>2012-07-05</leaveBalanceTotal.effectiveDate>
        <leaveBalanceTotal.lastPayEndDate>2012-07-05</leaveBalanceTotal.lastPayEndDate>
        <leaveBalanceTotal.totalDaysService>1459</leaveBalanceTotal.totalDaysService>
      </leaveBalanceTotal>
    </BB:Report_Data>
    

    希望对您有所帮助!如果您有任何问题,请告诉我。

    【讨论】:

    • 您忽略了复制最近 3 个模板中的属性。除非 OP 另有规定,否则假设它们可能存在将是一个更好的解决方案。由于排序,匹配表达式“node()|@*”的效率低于“@*|node()”。最好使用 local-name() 而不是 local-name(.) 。
    • @SeanB.Durkin - 感谢您的 cmets;非常感激。我没有包含属性,因为 OP 的原始问题没有包含它们。我尝试回答具体问题,而不是假设未明确说明的内容。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-29
    • 1970-01-01
    • 2017-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    相关资源
    最近更新 更多