Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/32.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
连接与XSLT共享属性值的标记的内容_Xslt_Xslt 2.0 - Fatal编程技术网

连接与XSLT共享属性值的标记的内容

连接与XSLT共享属性值的标记的内容,xslt,xslt-2.0,Xslt,Xslt 2.0,很显然,XSLT不是我的专长 Hpwever我有一些XHTML内容,我希望连接它包含的一些自定义标记的内容,但前提是它们共享给定的属性值 例如,我想把这个 <?xml version="1.0" encoding="UTF-8"?> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title /> </head> <body>

很显然,XSLT不是我的专长

Hpwever我有一些XHTML内容,我希望连接它包含的一些自定义标记的内容,但前提是它们共享给定的属性值

例如,我想把这个

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <title />
   </head>
   <body>
      <p>
         <mytag myid="0">Don't </mytag>
         <mytag myid="1">concatenate. </mytag>
         Other text
         <mytag myid="2">Text </mytag>
         <mytag myid="2">to </mytag>
         <mytag myid="2">concatenate. </mytag>
         More text
      </p>
   </body>
</html>


不要
连接
其他文本
正文
到
连接
更多文本

为此:

<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <title />
   </head>
   <body>
      <p>
         <mytag myid="0">Don't </mytag>
         <mytag myid="1">concatenate. </mytag>
         Other text
         <mytag myid="2">Text to concatenate. </mytag>
         More text
      </p>
   </body>
</html>


不要
连接
其他文本
要连接的文本。
更多文本

就我所掌握的XSLT而言:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<xsl:stylesheet xmlns:xhtml="http://www.w3.org/1999/xhtml" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                exclude-result-prefixes="xhtml"
                version="1.0">

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

<!-- Concatenate the contents of custom tags 'mytag'-->
<!-- that share an attribute myid value-->


<xsl:template match="//xhtml:mytag">

    <mytag>

        <xsl:variable name="this-id" select="@myid"/> 

        <xsl:attribute name="myid">
            <xsl:value-of select="$this-id"/>
        </xsl:attribute>

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

        <xsl:for-each  select="following-sibling::xhtml:mytag[@myid=$this-id]">
            <xsl:value-of select="."/>
        </xsl:for-each>

    </mytag>

</xsl:template>

</xsl:stylesheet>

然而,尽管我可能会尝试,但我无法解决如何停止已通过再次处理“following sibling”select处理的标记。因此,我的输出目前看起来非常悲惨:

<?xml version="1.0"?>
<html xmlns="http://www.w3.org/1999/xhtml">
   <head>
      <title/>
   </head>
   <body>
      <p>
         <mytag myid="0">Don't </mytag>
         <mytag myid="1">concatenate. </mytag>
         Other text
         <mytag myid="2">Text to concatenate. </mytag>
         <mytag myid="2">to concatenate. </mytag>
         <mytag myid="2">concatenate. </mytag>
         More text
      </p>
   </body>
</html>


不要
连接
其他文本
要连接的文本。
连接。
连接
更多文本

如果感觉像,我也应该回答我的问题——但我太笨了,看不见它


帮助?

在XSLT2.0中,使用

<xsl:template match="p">
  <xsl:for-each-group select="mytag" group-adjacent="@myid">
    <mytag myid="{current-grouping-key()}">
      <xsl:value-of select="string-join(current-group(), '')"/>
    </mytag>
  </xsl:for-each-group>
</xsl:template>

您可以调整当前模板,使其包含一个
xsl:if
,用于检查前面没有具有相同id的兄弟姐妹,以防止多次输出
mytag

<xsl:stylesheet xmlns:xhtml="http://www.w3.org/1999/xhtml" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                exclude-result-prefixes="xhtml"
                version="1.0">

<xsl:strip-space elements="*" />

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

<xsl:template match="xhtml:mytag">
   <xsl:variable name="this-id" select="@myid"/> 
   <xsl:if test="not(preceding-sibling::xhtml:mytag[@myid = $this-id])">
      <xsl:copy>
         <xsl:attribute name="myid">
            <xsl:value-of select="$this-id"/>
         </xsl:attribute>
         <xsl:value-of select="."/>
         <xsl:for-each select="following-sibling::xhtml:mytag[@myid=$this-id]">
            <xsl:value-of select="."/>
         </xsl:for-each>
      </xsl:copy>
   </xsl:if>
</xsl:template>
</xsl:stylesheet>

但是,根据您的需求,如果您的XML看起来像这样,则可能会“失败”

  <p>
     <mytag myid="0">Don't </mytag>
     <mytag myid="1">concatenate. </mytag>
     Other text
     <mytag myid="2">Text </mytag>
     <mytag myid="2">to </mytag>
     <mytag myid="2">concatenate. </mytag>
     More text
     <mytag myid="1">Concatenate separately. </mytag>
  </p>

不要
连接
其他文本
正文
到
连接
更多文本
分别连接。

给定的XSLT将生成以下内容

<body xmlns="http://www.w3.org/1999/xhtml">
   <p>
      <mytag myid="0">Don't </mytag>
      <mytag myid="1">concatenate. Concatenate separately. </mytag>
         Other text
         <mytag myid="2">Text to concatenate. </mytag>
         More text
         </p>
</body>


不要
连接分别连接。
其他文本
要连接的文本。
更多文本

这是因为以下同级轴获取所有后续同级,而不仅仅是紧跟当前节点的同级

如果你真的想要这个

<body xmlns="http://www.w3.org/1999/xhtml">
<p>
<mytag myid="0">Don't </mytag>
<mytag myid="1">concatenate. </mytag>
         Other text
         <mytag myid="2">Text to concatenate. </mytag>
         More text
         <mytag myid="1">Concatenate separately. </mytag>
</p>
</body>


不要
连接
其他文本
要连接的文本。
更多文本
分别连接。

然后,您必须逐个查看以下兄弟姐妹。试试这个XSLT

<xsl:stylesheet xmlns:xhtml="http://www.w3.org/1999/xhtml" 
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
                exclude-result-prefixes="xhtml"
                version="1.0">

<xsl:strip-space elements="*" />

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

<xsl:template match="xhtml:mytag">
   <xsl:variable name="this-id" select="@myid"/> 
   <xsl:if test="not(preceding-sibling::*[1][self::xhtml:mytag[@myid = $this-id]])">
      <xsl:copy>
         <xsl:attribute name="myid">
            <xsl:value-of select="$this-id"/>
         </xsl:attribute>
         <xsl:apply-templates select="self::*" mode="concatenate" />
      </xsl:copy>
   </xsl:if>
</xsl:template>

<xsl:template match="xhtml:mytag" mode="concatenate">
  <xsl:variable name="this-id" select="@myid"/> 
  <xsl:value-of select="." />
  <xsl:apply-templates select="following-sibling::*[1][self::xhtml:mytag[@myid = $this-id]]" mode="concatenate" />
</xsl:template>
</xsl:stylesheet>


您的问题标记为XSLT 2.0,但示例样式表是1.0。你能使用2.0吗?(这将取决于您使用的XSLT处理器。)如果在“更多文本”之后还有另一个
mytag myid=“2”
元素,会发生什么情况?您想将所有
mytag myid=“2”
同级元素合并在一起还是只合并相邻的元素?感谢您的回复-我的标记不正确,我在OS X上使用的是xlstproc,因此似乎仅限于xslt 1.0.Martin,在我的用例中,所有mytag myid=“2”同级元素都应该是相邻的,但如果它们不是,我只想合并相邻的。谢谢这是一个分组问题,XSLT 1.0的解决方案可以在这里找到:非常感谢您的回答,但是我标记得很糟糕,实际上我只能使用XSLT 1.0。我的错。很抱歉太棒了,蒂姆,我甚至知道它在做什么,这是一个结果。在我的环境中,共享myid值的标记无论如何都应该是连续的,因此第一个解决方案应该做到这一点。非常感谢