当且仅当它不存在时插入标记

时间:2015-06-21 21:36:37

标签: xslt

我想对XML文件进行XSLT转换,确保将标记<B>插入标记<A>中,当且仅当它不存在时才会插入标记<A>foo</A> should become <A><B>foo</B></A> <A>foo <x>bar</x></A> should become <A><B>foo <x>bar</x></B></A> <A><B>foo</B></A> should remain <A><B>foo</B></A> <A><B>foo <x>bar</x></B></A> should remain <A><B>foo <x>bar</x></B></A> 。例如:

<B>

因此<A>xxx <B>yyy</B></A> should become <A><B>xxx <B>yyy</B></B></A> <A><B>xxx</B> yyy</A> should become <A><B><B>xxx</B> yyy</B></A> 应该插入,当且仅当它“缺失”时才会插入。 我该怎么做?

编辑(回应评论时的澄清):

<A>

即,<B>应始终只有一个孩子,即==,如果已满足此要求,则不应采取任何措施。

2 个答案:

答案 0 :(得分:2)

我们可能需要根据您如何解决@ michael.hor257k指出的含糊不清情况进行调整,但这可以合理地解释您的要求:

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

  <xsl:output omit-xml-declaration="yes"/>

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

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

</xsl:stylesheet>

鉴于此输入XML:

<examples>
  <A>foo</A>
  <A>foo <x>bar</x></A>
  <A><B>foo</B></A>
  <A><B>foo <x>bar</x></B></A>
</examples>

它产生这个输出XML:

<examples>
  <A><B>foo</B></A>
  <A><B>foo <x>bar</x></B></A>
  <A><B>foo</B></A>
  <A><B>foo <x>bar</x></B></A>
</examples>

每次更新更新问题:

  

<A>应该始终只有一个孩子,这是<B>和。{   如果已满足此要求,则不应采取任何措施。

好的,然后从

更改上面的模板匹配
  <xsl:template match="A[not(B)]">

  <xsl:template match="A[not(B) or count(node()) > 1]">

然后给出这个新的输入XML:

<examples>
  <A>foo</A>
  <A>foo <x>bar</x></A>
  <A><B>foo</B></A>
  <A><B>foo <x>bar</x></B></A>
  <A>xxx <B>yyy</B></A>
  <A><B>xxx</B> yyy</A>
</examples>

新的XSLT将生成这个新的输出XML

<examples>
  <A><B>foo</B></A>
  <A><B>foo <x>bar</x></B></A>
  <A><B>foo</B></A>
  <A><B>foo <x>bar</x></B></A>
  <A><B>xxx <B>yyy</B></B></A>
  <A><B><B>xxx</B> yyy</B></A>
</examples>
根据要求

答案 1 :(得分:1)

  

<A>应始终只有一个孩子,即<B>

然后你真的在寻找没有小孩节点的A,或者有B以外的子节点或者有多个B个孩子:

XSLT 1.0

<xsl:stylesheet version="1.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="*"/>

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

<xsl:template match="A[not(node()) or node()[not(self::B)] or count(B) > 1]">
    <A>
        <B>
            <xsl:apply-templates select="@*|node()"/>
        </B>
    </A>
</xsl:template>

</xsl:stylesheet>

测试输入

<root>
    <A/>
    <A>foo</A>
    <A>foo <x>bar</x></A>
    <A><B>foo</B></A>
    <A><B>foo <x>bar</x></B></A>
    <A>xxx <B>yyy</B></A>
    <A><B>xxx</B> yyy</A>
    <A><B>foo</B><B>bar</B></A>
</root>

<强>结果

<?xml version="1.0" encoding="UTF-8"?>
<root>
   <A>
      <B/>
   </A>
   <A>
      <B>foo</B>
   </A>
   <A>
      <B>foo <x>bar</x>
      </B>
   </A>
   <A>
      <B>foo</B>
   </A>
   <A>
      <B>foo <x>bar</x>
      </B>
   </A>
   <A>
      <B>xxx <B>yyy</B>
      </B>
   </A>
   <A>
      <B>
         <B>xxx</B> yyy</B>
   </A>
   <A>
      <B>
         <B>foo</B>
         <B>bar</B>
      </B>
   </A>
</root>