【问题标题】:Xslt: How to change node text in element using a parameterXslt:如何使用参数更改元素中的节点文本
【发布时间】:2014-11-21 17:48:40
【问题描述】:

我需要更改某些节点的文本,类似于Update the text of an element with XSLT based on param

这是我的 XML:

<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
    <teiHeader>
        <fileDesc>
            <titleStmt>
                <title />
            </titleStmt>
            <publicationStmt>
                <p />
            </publicationStmt>
            <sourceDesc>
                <p />
            </sourceDesc>
        </fileDesc>
        <encodingDesc>
            <appInfo>
                <application ident="TEI_fromDOCX" version="2.15.0">
                    <label>DOCX to TEI</label>
                </application>
            </appInfo>
        </encodingDesc>
        <revisionDesc>
            <change>
                <date>$LastChangedDate: 2014-10-19$</date>
            </change>
        </revisionDesc>
    </teiHeader>
    <text>
        <body xml:id="test">
            <head>DICTIONARY</head>
            <entry>
                <form type="hyperlemma" xml:lang="cu">
                    <orth>абиѥ</orth>
                </form>
                <form type="lemma" xml:lang="cu">
                    <orth>абиѥ</orth>
                </form>
                <form type="variant" xml:lang="cu">
                    <orth>а̓бїе</orth>
                    <form type="hyperlemma" xml:lang="cu">
                        <orth>а̓бїе</orth>
                    </form>
                </form>
            </entry>
        </body>
    </text>
</TEI>

我现在想替换 &lt;orth&gt; 之间的文字

<form type="variant" xml:lang="cu">
    <orth>а̓бїе</orth>
    <form type="hyperlemma" xml:lang="cu">
        <orth>а̓бїе</orth>
    </form>
</form>

通过前一个节点中&lt;orth&gt;的内容

<entry>
    <form type="hyperlemma" xml:lang="cu">
        <orth>абиѥ</orth>
    </form>

为了得到以下输出:

<entry>
    <form type="hyperlemma" xml:lang="cu">
        <orth>абиѥ</orth>
    </form>
    <form type="lemma" xml:lang="cu">
        <orth>абиѥ</orth>      
    </form>
    <form type="variant" xml:lang="cu">
        <orth>а̓бїе</orth>
        <form type="hyperlemma" xml:lang="cu">
            <orth>абиѥ</orth>
        </form>
    </form>
 <entry>

当我使用以下样式表时

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" exclude-result-prefixes="xs" xpath-default-namespace="http://www.tei-c.org/ns/1.0" version="2.0">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*" />

<xsl:param name="replace_orth" select="entry/form[@type='hyperlemma' and @xml:lang='cu']/orth" />

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

<xsl:template match="form[@type='variant']/form[@type='hyperlemma' and @xml:lang='cu']/orth/text()">
    <xsl:value-of select="$replace_orth" />
</xsl:template>
</xsl:stylesheet>

然后我得到

<form type="variant" xml:lang="cu">
    <orth>а̓бїе</orth>
    <form type="hyperlemma" xml:lang="cu">
         <orth/>
</form>

所以&lt;orth&gt; 是空的。如果我将参数更改为

<xsl:param name="replace_orth" select="'new orth'" />

'new orth' 被打印出来。但由于每个条目的&lt;entry&gt;&lt;form type="hyperlemma" xml:lang="cu"&gt;&lt;orth&gt; 的内容不同(在上面的示例 XML 中我只显示一个条目),我不能使用“静态”字符串。

我需要改变什么?

感谢任何提示!

【问题讨论】:

    标签: xml xslt


    【解决方案1】:

    问题是您没有使用xsl:param 选择任何内容。您要么必须指定orth 的完整路径,要么使用//

    <xsl:param name="replace_orth" 
    select="/TEI/text/body/entry/form[@type='hyperlemma' and @xml:lang='cu']/orth" />
    

    <xsl:param name="replace_orth" 
    select="//entry/form[@type='hyperlemma' and @xml:lang='cu']/orth" />
    

    【讨论】:

    • 非常感谢!两个斜线起到了作用,我现在想知道为什么我自己没有看到...
    【解决方案2】:

    您必须从 xsl:stylesheet 元素中删除属性 xpath-default-namespace="http://www.tei-c.org/ns/1.0"。默认情况下,此属性将提到的 uri 作为命名空间 uri 应用于 xpaths 中的所有元素。

    示例: 如果您运行以下 XML(您输入的一部分):

    <entry>
    <form type="hyperlemma" xml:lang="cu">
         <orth>value</orth>
    </form>
    </entry>
    

    反对这个 XSLT:

    <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xpath-default-namespace="http://www.tei-c.org/ns/1.0" version="2.0">
    <xsl:output method="text" indent="yes" />
    <xsl:param name="replace_orth" select="entry/form[@type='hyperlemma' and @xml:lang='cu']/orth" />
    
    <xsl:template match="/">
        <xsl:value-of select="$replace_orth"/>
    </xsl:template>
    </xsl:stylesheet>
    

    输出什么都没有。 原因是默认情况下,所有 xpath 元素都应该具有命名空间http://www.tei-c.org/ns/1.0。因此,参数replace_orth 没有选择任何内容,因为输入 XML 的任何元素都没有该名称空间。

    但是,如果您将输入 XML 更改为以下内容:

    <entry xmlns="http://www.tei-c.org/ns/1.0">
    <form type="hyperlemma" xml:lang="cu">
         <orth>value</orth>
    </form>
    </entry>
    

    输出将是: value

    这是因为输入 XML 中所有元素的默认命名空间是 http://www.tei-c.org/ns/1.0

    【讨论】:

    • 非常感谢!我仍然很想知道为什么提到的属性会阻止 &lt;orth&gt; 元素的内容被替换。你能解释一下吗?
    • @LingamurthyCS 感谢您提供更详细的回答!我想我现在明白你的意思了。如果我在 both XML 和 XSL 中删除 http://www.tei-c.org/ns/1.0 并运行它,我会得到,就像你说的“价值”。但是只要&lt;entry&gt; 是另一个节点的子节点,比如说`,输出就什么都没有了。这才是真正让我困惑的地方。这仍然与命名空间有关还是有其他干扰?
    • 你能用你尝试的方法编辑你的问题吗?或者更好的是,问一个新的,如果这是新的东西。我没明白你的意思。。
    • LingamurthyCS:再次感谢!我编辑了我原来的问题,它现在应该是最初的样子,这意味着我在&lt;entry&gt; 之前添加了所有标签(我省略了它们,因为我从未认为它们是相关的)。在 XML 中,您实际上具有您建议在样式表中删除的命名空间属性。如果我针对样式表运行这个(更新的)XML,那么&lt;variant&gt; 下面的&lt;orth&gt; 是空的。 (我取消选中已解决的标记,不是因为我想要刻薄,而是因为您的建议不适用于更新的问题。)感谢您的耐心等待!
    猜你喜欢
    • 2023-03-30
    • 2018-12-30
    • 2020-08-11
    • 1970-01-01
    • 1970-01-01
    • 2013-03-26
    • 2019-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多