Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/14.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 Xpath/XSLT返回部分字符串_Xml_Xslt_Xpath - Fatal编程技术网

Xml Xpath/XSLT返回部分字符串

Xml Xpath/XSLT返回部分字符串,xml,xslt,xpath,Xml,Xslt,Xpath,我正在使用XSLT2.0和XPath2.0。我在写一个时遇到了问题,它会去掉段落的前导段落号,同时仍然保留段落中的所有元素。例如: <p>(1) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p> (1)本段可能包含斜体、粗体和其他元素 为此: <p> <b>(1)<b> This

我正在使用XSLT2.0和XPath2.0。我在写一个
时遇到了问题,它会去掉段落的前导段落号,同时仍然保留段落中的所有元素。例如:

<p>(1) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
(1)本段可能包含斜体、粗体和其他元素

为此:

<p>
  <b>(1)<b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.
</p>

(1) 本段可能有斜体、粗体和其他元素。

下面是我的一段详细代码,部分满足了我的需要:

    <xsl:template match="p[substring(.,1,1) = '('][string-length(substring-before(.,')')) &lt; 5]">
    <xsl:variable name="paragraphnumber">
        <xsl:value-of select="substring-after(substring-before(.,')'),'(')"/>
    </xsl:variable>
    <xsl:variable name="parenthesednumber" select="concat('(',$paragraphnumber,')')"/>
    <p>
        <b>
            <xsl:value-of select="$parenthesednumber"/>
        </b>
        <xsl:value-of select="translate(.,$parenthesednumber,'')"/>
    </p>
</xsl:template>    


模板匹配确保我们只匹配以
)开头的段落,结束语
之后只有5个字符,允许使用3个字符的段落编号或文本


我遇到的问题是的最后一个
值,我可以得到文本,但不能得到段落中的其他元素。

我认为最好是在段落中具有(n)个数字的第一个文本节点上进行匹配,这样您就可以自由地使用标识转换来复制/转换其他节点(文本/元素)在该段中

警告:我手头只有一个XPath/XSLT1.0处理器,但我相信这里没有1.0和2.0之间的区别

样式表:

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
    <xsl:template match="p/text()[1][substring(.,1,1) = '('][string-length(substring-before(.,')')) &lt; 5]">
        <xsl:variable name="paragraphnumber">
            <xsl:value-of select="substring-after(substring-before(.,')'),'(')" />
        </xsl:variable>
        <xsl:variable name="parenthesednumber" select="concat('(',$paragraphnumber,')')" />
        <b>
            <xsl:value-of select="$parenthesednumber" />
        </b>
        <xsl:value-of select="translate(.,$parenthesednumber,'')" />
    </xsl:template>
    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()" />
        </xsl:copy>
    </xsl:template>
</xsl:stylesheet>

输出:

<p><b>(1)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
(1)本段可能包含斜体、粗体和其他元素


我认为,在这里使用单独的模板是一种更好的方法。通过这样做,您可以确保“权力划分”,并更容易地找出错误代码

下面的样式表通过
matches()
使用XSLT中的正则表达式功能:

输出

<?xml version="1.0" encoding="UTF-8"?><p><b>(1)</b>This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
为什么您的方法无效

我假设这一行:

<xsl:value-of select="translate(.,$parenthesednumber,'')"/>


您打算输出
的剩余内容。但是,您只输出
p
元素的文本内容,而不输出其子元素。您还需要明确声明它们也应该被处理-例如,通过使用
apply templates

我将使用以下方法:

<p>(2) Text1 <b/>(1) Text2</p>
<xsl:template match="p/text()[1]">
  <xsl:analyze-string select="." regex="\(\d+\)">
   <xsl:matching-substring>
     <b><xsl:value-of select="."/></b>


要将“p”元素转换为在第一个文本节点中包含额外“b”元素的元素。

正如Michael Kay所建议的,您可以执行以下操作

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:template match="p/text()[1]">
        <xsl:analyze-string select="." regex="\(.{{1,3}}\)">
            <xsl:matching-substring>
                <b><xsl:value-of select="."/></b>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>
</xsl:stylesheet>

它搜索第一个文本节点,以“(”开头,以“)”结尾,内有1-3个字符。应用于XML输入时,如:

<root>
    <p>(abc4) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p>(123) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p>(1ab) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p>(a1) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
</root>

(abc4)本段可能有斜体、粗体和其他元素

(123)本段可包含斜体、粗体和其他元素

(1ab)本段可包含斜体、粗体和其他元素

(a1)本段可采用斜体、粗体和其他元素

它产生:

<root>
    <p>(abc4) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p><b>(123)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p><b>(1ab)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p><b>(a1)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
</root>

(abc4)本段可能有斜体、粗体和其他元素

(123)本段可包含斜体、粗体和其他元素

(1ab)本段可包含斜体、粗体和其他元素

(a1)本段可采用斜体、粗体和其他元素


我想知道作为两个模板,这是否会更好…一个是发现段落并插入p的子::b。然后模板2将现在不需要的(a)从段落文本的开头移除?这不会从任何文本节点的开头移除
\([0-9]+\)
,而不仅仅是
之后的第一个文本节点吗?也就是说,如果您的输入是
Text1(1)Text2

,它也会删除(1)?您是对的。谢谢你发现这个。我将更新我的样式表。OP希望允许使用3个字符的段落编号或文本。此
不会选择以
(abc)
开头的
节点。我选择了Joel的答案,因为我喜欢使用analyze字符串。但是我也喜欢这个答案。我第一次使用。。我喜欢。
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

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

    <xsl:template match="p/text()[1]">
        <xsl:analyze-string select="." regex="\(.{{1,3}}\)">
            <xsl:matching-substring>
                <b><xsl:value-of select="."/></b>
            </xsl:matching-substring>
            <xsl:non-matching-substring>
                <xsl:value-of select="."/>
            </xsl:non-matching-substring>
        </xsl:analyze-string>
    </xsl:template>
</xsl:stylesheet>
<root>
    <p>(abc4) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p>(123) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p>(1ab) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p>(a1) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
</root>
<root>
    <p>(abc4) This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p><b>(123)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p><b>(1ab)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
    <p><b>(a1)</b> This paragraph may have <i>italics</i>, <b>bold</b> and other elements.</p>
</root>