Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在XML文档中的其他可选元素之间插入可选元素。。。根据模式?_C#_Xml_Xslt_Infopath - Fatal编程技术网

C# 在XML文档中的其他可选元素之间插入可选元素。。。根据模式?

C# 在XML文档中的其他可选元素之间插入可选元素。。。根据模式?,c#,xml,xslt,infopath,C#,Xml,Xslt,Infopath,真的很难把这个解释和一个准确的标题结合起来,但我试过了 无论如何,问题很简单 给定以下xml: <Parent> <Child/> <Child/> <Child/> <Child/> <!-- Trying to insert an element here --> <OtherChild/> <OtherChild/> <OtherChild/>

真的很难把这个解释和一个准确的标题结合起来,但我试过了

无论如何,问题很简单

给定以下xml:

<Parent> 
  <Child/> 
  <Child/> 
  <Child/> 
  <Child/> 
  <!-- Trying to insert an element here -->
  <OtherChild/>
  <OtherChild/>
  <OtherChild/>
</Parent>

并假设如下:

<Parent> 
  <Child/> 
  <Child/> 
  <Child/> 
  <Child/> 
  <!-- Trying to insert an element here -->
  <OtherChild/>
  <OtherChild/>
  <OtherChild/>
</Parent>
  • 我们知道这个模式,并且可以访问它
  • 根据架构,所有元素都是可选的,但必须按顺序显示
  • 我们插入的元素也可以是可选的
  • 不保证存在任何父节点或其他子节点,也不保证存在多少子节点
  • 嵌套的深度不一定是1,它可以是多个嵌套元素
我的解决方案:

<Parent> 
  <Child/> 
  <Child/> 
  <Child/> 
  <Child/> 
  <!-- Trying to insert an element here -->
  <OtherChild/>
  <OtherChild/>
  <OtherChild/>
</Parent>
  • 检查是否存在我们正在插入的任何子项
  • 递归方法检查以前的同级(需要知道我们插入的元素之前的同级),然后检查父级
  • 结果:

    <Parent> 
      <Child/> 
      <Child/> 
      <Child/> 
      <Child/> 
      <!-- Trying to insert an element here -->
      <OtherChild/>
      <OtherChild/>
      <OtherChild/>
    </Parent>
    
    A.如果我们试图插入的元素存在,我们将在之后插入
    B.如果存在前面的兄弟姐妹,我们在后面插入。
    C.如果不存在前面的兄弟姐妹,但父代不存在,则我们将前置到父代。
    D.从那里沿着树向上走,我们将继续走到当前父级的下一个父级或前一个兄弟级,直到找到一个存在的父级,然后将整个树插入到我们尝试插入的元素

    我目前在C代码中这样做,首先使用模式来发现前面的同级,然后迭代地尝试选择一个,直到找到一个或到达列表的末尾。然后我尝试发现父元素,然后重复将父元素作为要插入的元素

    问题:

    <Parent> 
      <Child/> 
      <Child/> 
      <Child/> 
      <Child/> 
      <!-- Trying to insert an element here -->
      <OtherChild/>
      <OtherChild/>
      <OtherChild/>
    </Parent>
    
    有没有可能用另一种更快、更高效、更整洁、更好的方式来实现这一点

    我只是在学习XSLT,以及它是否可以通过一个完美的转换来完成(注意必须是XSLT1.0)

    另一种聪明的最小化工作的方法是,目前它基本上必须遍历整个树,直到它到达一个现有的节点,这可能需要大量的工作

    注意:作为参考,这实际上是在InfoPath中使用的,我将在其中处理主数据源。特别是我指的是重复表,用户可以从表中删除所有行,此时任何试图向该表添加行的代码都可能会遇到非常困难的时间

    InfoPath本身能够像pie一样轻松地向表中添加新行,如果我能弄清楚它们是如何管理的,那就太好了。作为替代,我很高兴能有一个简单的方法来做到这一点

    我已经有了解决这个问题的办法,正如我所说的,我只是想找一些人来提出一些想法,看看我是否能得到一些改进。我很感激你提出的任何建议


    谢谢:)

    这不是一个完整的答案,但如果你能给我一些澄清,我也许能解决一些问题

    下面给出了一个类似xml的xml:

    <root>
        <parent>
            <child>child1</child>
            <child>child2</child>
            <otherChild>other1</otherChild>
        </parent>
    </root>
    
    
    孩子1
    孩子2
    其他1
    
    将其转化为:

    <?xml version="1.0" encoding="UTF-8"?> 
    <root>
        <parent>
            <child>child1</child>    
            <child>child2</child>
            <insertedChild>inserted1</insertedChild>
            <otherChild>other2</otherChild>
        </parent>
    </root>
    
    
    孩子1
    孩子2
    插入1
    其他2
    
    这是xsl:

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0"> 
      <xsl:template match="/root"> 
        <xsl:for-each select=".">
          <xsl:element name="root">
              <xsl:for-each select="parent">
                  <xsl:element name="parent">
                      <xsl:copy-of select="child" />
                      <xsl:element name="insertedChild">
                        inserted1
                      </xsl:element>
                     <xsl:copy-of select="otherChild" />            
                  </xsl:element>
               </xsl:for-each>      
          </xsl:element>
        </xsl:for-each>
      </xsl:template> 
    </xsl:stylesheet>
    
    
    插入1
    
    在我们希望添加的元素之前和之后,可以对任意数量的不同元素进行更改

    我从问题描述中没有得到的是,要添加的元素是否位于任何位置;也就是说,我们事先不知道我们希望以什么样的模式结束

    这是您需要为多个元素运行的转换吗?如果是这种情况,您可能需要创建多个xsl文件或将它们包含在其中。无论哪种方式,它都会有点复杂

    然而,XSL对参数化是开放的,例如,您可以选择插入元素的名称和值,如下所示:

    <?xml version="1.0"?>
    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"  version="1.0"> 
    <xsl:param name="insertedChild"></xsl:param>
    <xsl:param name="valueOfInsertedChild"></xsl:param>
      <xsl:template match="/root"> 
        <xsl:for-each select=".">
            <xsl:element name="root">
                <xsl:for-each select="parent">
                    <xsl:element name="parent">
                        <xsl:copy-of select="child" />
                        <xsl:element name="{$insertedChild}">
                            <xsl:value-of select="$valueOfInsertedChild" />
                        </xsl:element>
                        <xsl:copy-of select="otherChild" />         
                    </xsl:element>
                </xsl:for-each>     
            </xsl:element>
        </xsl:for-each>
      </xsl:template> 
    </xsl:stylesheet>
    
    
    

    我希望这和你想要的有点接近。请为我澄清上述几点,我们可能会找到更好的解决办法。

    好的,我相信我明白了。声明有4个参数,定义插入元素的名称、值,一个参数定义前一个元素,一个参数定义父元素

    两个限制:

    • 需要知道根(文档)元素(此处 “根”)
    • 无法获取混合内容(即,将节点插入到 具有字符数据而不是其他节点的另一个节点)

      
      A.
      A.
      小孩
      父母亲
      

    出于性能原因,我不确定它是如何工作的,但您可以尝试一下。我认为这与你的要求非常接近。让我知道这是怎么回事。:)

    谢谢你的回答,虽然不是很好,但可能是一个好的开始。事实是,我希望这是更一般的。。。我们可以访问该模式,但它可能会不时发生变化。任何变换都必须动态生成。被插入的元素可以是任何名称,可以是任何嵌套深度,可以是任何其他元素。此外,如果没有父元素,则变换不会插入元素。我需要