如何使用XPATH / XSLT检查子节点是否存在,以便我不为其添加重复节点?

时间:2015-02-13 19:04:47

标签: xml xslt xpath

我想消除注入重复节点(如果它们已存在于XML源文件中)。我当前的代码正确插入了我想要的内容,但没有检查节点是否已经存在。

这是我需要操作的原始XML文件:

    <?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <fields>
        <fullName>Data_Check_Comments__c</fullName>
        <description>Checking Data for Company</description>
        <label>Data Check Comments</label>
    </fields>
    <fields>
        <fullName>My_Test_Obj__c</fullName>
        <description>General info about the test object.</description>
        <inlineHelpText>This is simply a test object.</inlineHelpText>
        <label>My Test Obj</label>
    </fields>
</CustomObject>

这是我想要的输出XML:

<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
    <fields>
        <inlineHelpText>fields</inlineHelpText>
        <fullName>Data_Check_Comments__c</fullName>
        <description>Checking Data for Company</description>
        <label>Data Check Comments</label>
    </fields>
    <fields>
        <!--***I don't want this duplicate*** inlineHelpText xmlns="">fields</inlineHelpText-->
        <fullName>My_Test_Obj__c</fullName>
        <description>General info about the test object.</description>
        <inlineHelpText>This is simply a test object.</inlineHelpText>
        <label>My Test Obj</label>
    </fields>
</CustomObject>

最后这是我当前的xlst:

<?xml version="1.0" ?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0" xmlns:a="http://soap.sforce.com/2006/04/metadata">

  <xsl:template match="a:CustomObject/*">
    <xsl:copy>
      <xsl:element name="inlineHelpText">
        <xsl:value-of select="name(.)"/>
      </xsl:element>

      <xsl:call-template name="copy-children"/>
    </xsl:copy>
  </xsl:template>

  <xsl:template name="copy-children">
    <xsl:copy-of select="./*"/>
  </xsl:template>

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

2 个答案:

答案 0 :(得分:1)

很难理解你的问题是什么,以及只是一个例子。这样的事情对你有用吗?

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:a="http://soap.sforce.com/2006/04/metadata"
exclude-result-prefixes="a">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<xsl:strip-space elements="*"/>

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

<xsl:template match="a:fields[not(a:inlineHelpText)]">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
        <inlineHelpText xmlns="http://soap.sforce.com/2006/04/metadata">fields</inlineHelpText>
    </xsl:copy>
</xsl:template>

</xsl:stylesheet>

答案 1 :(得分:1)

其实我找出了问题所在。对不起,如果问题不明确。通过使用if和下面的语法,我可以忽略它们已经存在的子节点。感谢。

<xsl:if test="not(descendant::*[local-name()='inlineHelpText'])">
     <xsl:element name="inlineHelpText">
        <xsl:value-of select="name(.)"/>
     </xsl:element>
</xsl:if>