Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.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
Xml 添加节点';将文本字符串插入其中';她以前的兄弟姐妹';子文本字符串_Xml_Xslt_Xpath_Xslt 2.0 - Fatal编程技术网

Xml 添加节点';将文本字符串插入其中';她以前的兄弟姐妹';子文本字符串

Xml 添加节点';将文本字符串插入其中';她以前的兄弟姐妹';子文本字符串,xml,xslt,xpath,xslt-2.0,Xml,Xslt,Xpath,Xslt 2.0,我正试图将一个节点移动到它的前一个兄弟节点的子节点中,而事实上,所有节点都在同一个级别上,这对我来说有点棘手 我的输入说明: <dl> <dlentry> <dt> Title 1 </dt> <dd> Title 1's definition </dd> <dt> Title 2 </dt> <dd> Title 2's defini

我正试图将一个节点移动到它的前一个兄弟节点的子节点中,而事实上,所有节点都在同一个级别上,这对我来说有点棘手

我的输入说明:

<dl>
   <dlentry>
      <dt> Title 1 </dt>
      <dd> Title 1's definition </dd>
      <dt> Title 2 </dt>
      <dd> Title 2's definition </dd> 
      <dt> Title 3 </dt>
      <dd> Title 3's definition </dd>
   </dlentry>
</dl> 
<p> part of title 3's definition </p>
<p> another part of title 3's definition </p>

标题1
标题1的定义
标题2
标题2的定义
标题3
标题3的定义
第3篇定义的一部分

第3篇定义的另一部分

我试图做的是将底部的2个
元素连接到
中最后一个
元素文本的末尾,因为它们是“Title 3”定义的一部分

期望输出:

<dl>
   <dlentry>
      <dt> Title 1 </dt>
      <dd> Title 1's definition </dd>
      <dt> Title 2 </dt>
      <dd> Title 2's definition </dd> 
      <dt> Title 3 </dt>
      <dd> Title 3's definition part of title 3's definition another part of title 3's  definition </dd>
   </dlentry>
</dl>
<?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:template match="/doc">
  <xsl:for-each select="dl">
   <dl>
    <xsl:for-each select="dlentry">
      <xsl:apply-templates select="dt|dd"/>
    </xsl:for-each>
   </dl>
  </xsl:for-each>
 </xsl:template>

 <xsl:template match="dt">
  <dt><xsl:value-of select="."/></dt>
 </xsl:template>

 <xsl:template match="dd">
  <dd>
    <xsl:value-of select="."/>
    <!-- Check if this is the last element (= no dd/dd after) -->
    <xsl:if test="not(following-sibling::*)">
     <!-- Select dl's next sibling, if it's a <p> -->
     <xsl:for-each select="../../following-sibling::*[1][name() = 'p']">
      <!-- Call recursive template -->
      <xsl:call-template name="concat"/>
     </xsl:for-each>
    </xsl:if>
  </dd>
 </xsl:template>

 <xsl:template name="concat">
   <xsl:value-of select="."/>
   <!-- Select p's next sibling, if it's a <p> -->
   <xsl:for-each select="following-sibling::*[1][name() = 'p']">
    <!-- Call recursive template -->
    <xsl:call-template name="concat"/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

标题1
标题1的定义
标题2
标题2的定义
标题3
第3篇定义第3篇定义的一部分第3篇定义的另一部分
我要处理的另一个问题是,由于XHTML在我的源文档中有多么糟糕,我需要对那些
元素的文本进行正则表达式匹配,以确保它不会在文档中的任何其他地方出现

我能够根据需要成功地插入第一个
的文本,但是我很难让它工作,因此我可以进行正则表达式匹配,也可以将第二个元素的文本插入到所需的位置

下面是我的样式表中的代码片段,使用XSLT2.0

<xsl:analyze-string select="."
      regex="my regex expression here">

<xsl:template match="dlentry">

  <xsl:matching-substring>
    <dlentry>
     ** <xsl:copy-of select="node()[ position() lt last()]"/>
         <dd>
           <xsl:copy-of select="node()[last()]/text()" />
           <xsl:copy-of select=" parent::node()/following-sibling::node()[1]/text()"/>
         </dd>
    </dlentry>
  </xsl:matching-substring>

  <xsl:non-matching-substring>
      <xsl:value-of select=".">
  </xsl:non-matching-substring>

</xsl:template>

<xsl:template match="p[preceding-sibling::node()[1][self::node()[name(.)='dl']]]" />
<xsl:template match="p[preceding-sibling::node()[2][self::node()[name(.)='dl']]]" />

** 
在带有**星号的代码行中,Saxon抛出一个错误,说“这里不能使用Axis step child::node():上下文项是一个原子值”。我不熟悉分析字符串,但如果我在分析字符串之外的模板中运行我的选择副本,它会正常运行

很抱歉,这个问题有点长,但我想分享到目前为止我所拥有的一切


提前感谢。

不确定效率,但以下xsl应生成所需的输出:

<dl>
   <dlentry>
      <dt> Title 1 </dt>
      <dd> Title 1's definition </dd>
      <dt> Title 2 </dt>
      <dd> Title 2's definition </dd> 
      <dt> Title 3 </dt>
      <dd> Title 3's definition part of title 3's definition another part of title 3's  definition </dd>
   </dlentry>
</dl>
<?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:template match="/doc">
  <xsl:for-each select="dl">
   <dl>
    <xsl:for-each select="dlentry">
      <xsl:apply-templates select="dt|dd"/>
    </xsl:for-each>
   </dl>
  </xsl:for-each>
 </xsl:template>

 <xsl:template match="dt">
  <dt><xsl:value-of select="."/></dt>
 </xsl:template>

 <xsl:template match="dd">
  <dd>
    <xsl:value-of select="."/>
    <!-- Check if this is the last element (= no dd/dd after) -->
    <xsl:if test="not(following-sibling::*)">
     <!-- Select dl's next sibling, if it's a <p> -->
     <xsl:for-each select="../../following-sibling::*[1][name() = 'p']">
      <!-- Call recursive template -->
      <xsl:call-template name="concat"/>
     </xsl:for-each>
    </xsl:if>
  </dd>
 </xsl:template>

 <xsl:template name="concat">
   <xsl:value-of select="."/>
   <!-- Select p's next sibling, if it's a <p> -->
   <xsl:for-each select="following-sibling::*[1][name() = 'p']">
    <!-- Call recursive template -->
    <xsl:call-template name="concat"/>
   </xsl:for-each>
 </xsl:template>
</xsl:stylesheet>

这是我测试它的输入:

<doc>
 <dl>
   <dlentry>
      <dt> Title 1 </dt>
      <dd> Title 1's definition </dd>
      <dt> Title 2 </dt>
      <dd> Title 2's definition </dd>
      <dt> Title 3 </dt>
      <dd> Title 3's definition </dd>
   </dlentry>
 </dl>
 <p> part of title 3's definition </p>
 <p> another part of title 3's definition </p>
</doc>

标题1
标题1的定义
标题2
标题2的定义
标题3
标题3的定义
第3篇定义的一部分

第3篇定义的另一部分


这个简短而简单的XSLT 1.0(当然也是XSLT 2.0):


应用于提供的XML文档时

<html>
    <dl>
        <dlentry>
            <dt> Title 1 </dt>
            <dd> Title 1's definition </dd>
            <dt> Title 2 </dt>
            <dd> Title 2's definition </dd>
            <dt> Title 3 </dt>
            <dd> Title 3's definition </dd>
        </dlentry>
    </dl>
    <p> part of title 3's definition </p>
    <p> another part of title 3's definition </p>
</html>

标题1
标题1的定义
标题2
标题2的定义
标题3
标题3的定义
第3篇定义的一部分

第3篇定义的另一部分

生成所需的正确结果:

<html>
   <dl>
      <dlentry>
         <dt> Title 1 </dt>
         <dd> Title 1's definition </dd>
         <dt> Title 2 </dt>
         <dd> Title 2's definition </dd>
         <dt> Title 3 </dt>
         <dd> Title 3's definition  part of title 3's definition  another part of title 3's definition </dd>
      </dlentry>
   </dl>
</html>

标题1
标题1的定义
标题2
标题2的定义
标题3
第3篇定义第3篇定义的一部分第3篇定义的另一部分

我这边似乎无法实现这一点,在您的for-each语句中,您似乎希望选择dlentry的下一个同级p,但dlentry没有同级。德兰特里和p在不同的层次上。dl和p在同一个级别上,如果空格在我的问题中没有足够清楚,那么很抱歉。啊,很抱歉,我匆忙编写了代码注释,看起来它们与功能不匹配。它应该说明“如果dl的下一个同级元素是p元素”。我使用测试工具测试了xsl。请注意,我必须添加一个名为doc的根节点。啊,好的,我将尝试在我的实现中使用它。再次感谢Dimitre!非常有效的方法。@Laterade,也很方便:)与我的解决方案相比,实际上有两个不同之处。第一个区别是,该解决方案需要将整个dom树加载到内存中,以便创建所需的键索引。第二个区别在于如何处理-元素。此解决方案将包括dl之后的所有元素。我的解决方案将只包括那些直接位于-元素之后的-元素。您可以通过在元素之间放置一个标记来尝试输出的差异。话虽如此,这仍然是一个很好的解决方案,值得+1。@SamiKorhonen,实际上,XSLT要求源XML文档的完整表示(DOM或类似的东西)在RAM中——这不仅仅限于使用键。至于第二句话,OP没有给我们提供更具体的XML文档,我不想徒劳地猜测。如果提供了更具体的文档,修改此解决方案以考虑新的细节就很简单了。感谢upvote。虽然大多数实现都会在内存中加载输入文档的完整表示,但标准兼容处理器的编写方式只能将文档的某些部分保留在内存中。但是我认为关于实现的讨论是离题的,所以我将把它留在这里。