Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.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 如何在xslt中找到从节点到其子节点的相对xpath表示法?_Xml_Xslt_Xpath - Fatal编程技术网

Xml 如何在xslt中找到从节点到其子节点的相对xpath表示法?

Xml 如何在xslt中找到从节点到其子节点的相对xpath表示法?,xml,xslt,xpath,Xml,Xslt,Xpath,我对xslt比较陌生,但我有幸设计了一个巨大的xml文件的样式。现在我被困在一个地方,无法继续前进。假设xml文件的结构有点像 <xxx> ....... ....... ....... <Field id="123" type="fld" elem="3"> <td:value passed="true"> 25 </td:value> </Field> ....... ....... ....... </xxx&g

我对xslt比较陌生,但我有幸设计了一个巨大的xml文件的样式。现在我被困在一个地方,无法继续前进。假设xml文件的结构有点像

<xxx>
.......
.......
.......
 <Field id="123" type="fld" elem="3">
   <td:value passed="true"> 25 </td:value>
 </Field>
.......
.......
.......

</xxx>

.......
.......
.......
25
.......
.......
.......
我当前在字段节点中。如果我做一个
它会给出“Field”,如果我做一个
我会得到“fld”。但是如果我做一个
,我会得到
中的值,即25

我关心的是,我需要在td:value中获取'passed'属性的值。如果从当前位置使用以下模板,则可以访问该属性

<xsl:apply-templates select="*[@passed]" />

  <xsl:template match="*[@passed]" >
       <xsl:value-of select="@passed" />
     </xsl:template>

但问题是“passed”属性可能并不总是存在,因此我需要只使用节点名称访问
节点

我试过了

<xsl:apply-templates select=".//td" />
<xsl:apply-templates select=".//td:value" />
<xsl:apply-templates select=".//*" />
<xsl:apply-templates select=".*" />
<xsl:apply-templates select="td" />


似乎什么都不管用。如何从字段节点到达td:value节点

只是澄清一下,您当前位于字段元素上,并且您正试图选择子td:value以获取其@传递的属性,但是如果该属性不存在,则您希望获取元素的值

好吧,你能做的就是先换掉这个

<xsl:apply-templates select="*[@passed]" />

就这样

<xsl:apply-templates select="*" />

然后,您需要两个匹配的模板;一个用于属性存在时,另一个用于捕获其他情况

<xsl:template match="Field/*[@passed]" >
   <xsl:value-of select="@passed" />
</xsl:template>

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

当您有两个这样的模板时,XSLT将首先匹配更具体的模板。因此,如果存在@passed属性,则第一个模板将始终匹配(即使第二个模板也与之匹配)。当没有一个存在时,将使用第二个

编辑:如果您不想指定元素名称,您可以将模板替换为以下内容

<xsl:template match="*[@passed]" >
   <xsl:value-of select="@passed" />
</xsl:template>

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

但是,这些元素将开始匹配可能影响XSLT其他部分的所有元素。因此,您可能必须在这里使用模式参数

<xsl:apply-templates select="*" mode="Field" />

<xsl:template match="*[@passed]" mode="Field" >
   <xsl:value-of select="@passed" />
</xsl:template>

<xsl:template match="*" mode="Field" >
   <xsl:value-of select="." />
</xsl:template>

只是澄清一下,您当前位于字段元素上,您正试图选择子td:value以获取其@传递的属性,但如果该属性不存在,则您希望获取元素的值

好吧,你能做的就是先换掉这个

<xsl:apply-templates select="*[@passed]" />

就这样

<xsl:apply-templates select="*" />

然后,您需要两个匹配的模板;一个用于属性存在时,另一个用于捕获其他情况

<xsl:template match="Field/*[@passed]" >
   <xsl:value-of select="@passed" />
</xsl:template>

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

当您有两个这样的模板时,XSLT将首先匹配更具体的模板。因此,如果存在@passed属性,则第一个模板将始终匹配(即使第二个模板也与之匹配)。当没有一个存在时,将使用第二个

编辑:如果您不想指定元素名称,您可以将模板替换为以下内容

<xsl:template match="*[@passed]" >
   <xsl:value-of select="@passed" />
</xsl:template>

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

但是,这些元素将开始匹配可能影响XSLT其他部分的所有元素。因此,您可能必须在这里使用模式参数

<xsl:apply-templates select="*" mode="Field" />

<xsl:template match="*[@passed]" mode="Field" >
   <xsl:value-of select="@passed" />
</xsl:template>

<xsl:template match="*" mode="Field" >
   <xsl:value-of select="." />
</xsl:template>

您需要声明在输入XML中分配给
td:value
td
前缀的名称空间。例如:

<foo xmlns:td="urn:td">
  <Fieldid="123" type="fld" elem="3">
    <td:value passed="true"> 25 </td:value>
  </Field>
</foo>

25
XSLT可能类似于:

<xsl:template match="Field">
  <xsl:if test="td:value@passed" xmlns:td="urn:td">
    <xsl:value-of select="td:value"/>
  </xsl:if>
</xsl:template>


重要的是名称空间必须与输入文档中的名称空间相同,XSLT文档中的前缀是否命名不同并不重要。如果可能,并且如果所有XML都在您的控制之下,为了清楚起见,应该是这样。

您需要声明在输入XML中分配给
td:value
前缀
td
的名称空间。例如:

<foo xmlns:td="urn:td">
  <Fieldid="123" type="fld" elem="3">
    <td:value passed="true"> 25 </td:value>
  </Field>
</foo>

25
XSLT可能类似于:

<xsl:template match="Field">
  <xsl:if test="td:value@passed" xmlns:td="urn:td">
    <xsl:value-of select="td:value"/>
  </xsl:if>
</xsl:template>


重要的是名称空间必须与输入文档中的名称空间相同,XSLT文档中的前缀是否命名不同并不重要。如果可能,并且所有XML都在您的控制之下,为了清楚起见,它应该在您的XSLT知道
td:
名称空间吗?是的,存在xmlns:td=“somewebsite”名称空间声明。您的XSLT知道
td:
名称空间吗?是的,存在xmlns:td=“somewebsite”名称空间声明。嘿,蒂姆,谢谢你的快速回答。我忘了再提一个。标记“字段”不一致,在每种情况下可能不同。那么现在如何引用模板而不是“Field/*[@passed]”和“Field/*”?啊,我完全忘记了mode参数。现在很好用。非常感谢你的帮助,伙计!嘿,蒂姆,谢谢你的快速回答。我忘了再提一个。标记“字段”不一致,在每种情况下可能不同。那么现在如何引用模板而不是“Field/*[@passed]”和“Field/*”?啊,我完全忘记了mode参数。现在很好用。非常感谢你的帮助,伙计!Paulo,
会不会在模板中没有提到xmlns:td?是否强制执行?要特别匹配
td:value
,是的。您可以在任何包含节点中声明名称空间,如root
xsl:stylesheet
。但是,如果您真的想忽略名称空间,请尝试
。Paulo,
在模板中不提及xmlns:td,它会工作吗?是否强制执行?要特别匹配
td:value
,是的。您可以在任何包含节点中声明名称空间,如root
xsl:stylesheet
。但是,如果确实要忽略名称空间,请尝试