【问题标题】:XSLT Transformation to validate rules in XML documentXSLT 转换以验证 XML 文档中的规则
【发布时间】:2012-03-19 06:59:06
【问题描述】:

XSLT 转换中的另一个新手问题。 (我之前也问过类似的问题,但在这种情况下,XML 有不同的格式)。

我有一个 xml 文档,我需要使用 xslt 进行大量验证。这将使用 xsltproc 工具完成。

<?xml version="1.0" ?>
<Company id="1" ...>
   <Name>blah</Name>
   <Location>
     <Address>zzz</Address>
     <City>aaa</City>
     .....
   </Location>
   ....
   <Manager id="m1" mincount="4" grade="10"...>
      <Employee id="e1"/>
      <Employee id="e2"/>
      .....
   </Manager>
   .....
</Company>

<Employee_List>
  <Employee id="e1" grade="9" Location="New York" p1="value" p2="value"....... />
  <Employee id="e2" grade="8" Location="New York" p1="value" p2="value"....... />
  ......
</Employee_List>

我只需要对&lt;Manager&gt;&lt;Employee_List&gt; 标签进行以下验证 即我不关心公司位置标签等。请注意xml文档有&lt;company&gt;&lt;Employee_List&gt;标签。

  1. 经理下的员工人数应 >= mincount。
  2. 经理下属员工的等级应该是
  3. 经理下的所有员工都应位于同一位置。 (我需要额外的检查,比如员工的财产 p1 和 p2 也应该匹配)。

TIA 并感谢任何帮助!

待验证的新规则(于 2012 年 3 月 5 日添加)。 1. p1 属性必须是 ALPHA 或 BETA(字符串),不能是其他任何东西。此 xsl 适用于单个员工,而不适用于多个员工。

    <xsl:apply-templates mode="rule5" select=
  "*/*/Manager[not(key('kEmpById', Employee/@id)/@p1 = 'ALPHA' or
               key('kEmpById', Employee/@id)/@p1 = 'BETA')
              ]
  "/>
  1. 下面的员工 ID 应该是唯一的。我试过这个 xsl,但它不起作用:(

    <xsl:apply-templates mode="rule6" select=
    

    "//Manager[key('kEmpById', Employee[2]/@id)/@id = 键('kEmpById',员工/@id)/@id ] "/>

TIA!

【问题讨论】:

  • 对于上一个问题 (stackoverflow.com/questions/9306433/…),您尝试过什么以及最终做了什么?
  • 顺便说一句,反对票不是我投的。
  • DevNull:仅解析 Manager 标签还没有运气。我已经解析了所有标签的 xsl :(

标签: xml xslt transformation xml-validation


【解决方案1】:

类似于以下内容

<xsl:stylesheet version="1.0"
 xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
 <xsl:output omit-xml-declaration="yes" indent="yes"/>

 <xsl:key name="kEmpById" match="Employee" use="@id"/>

 <xsl:template match="/">
  <xsl:apply-templates mode="rule1" select=
  "*/*/Manager[@mincount > count(Employee)]"/>

  <xsl:apply-templates mode="rule2" select=
  "*/*/Manager[key('kEmpById', Employee/@id)/@grade > @grade]"/>

  <xsl:apply-templates mode="rule3" select=
  "*/*/Manager[key('kEmpById', Employee[2]/@id)/@Location
             !=
               key('kEmpById', Employee/@id)/@Location
              ]
  "/>
 </xsl:template>

 <xsl:template match="Manager" mode="rule1">
  Manager id = "<xsl:value-of select="@id"/>" has too few employees.

 </xsl:template>

 <xsl:template match="Manager" mode="rule2">
  Manager id = "<xsl:value-of select="@id"/>" has employees with higher grade than his own.

 </xsl:template>

 <xsl:template match="Manager" mode="rule3">
  Manager id = "<xsl:value-of select="@id"/>" has employees at different locations.

 </xsl:template>
</xsl:stylesheet>

当此转换应用于提供的 XML 文档时(经过编辑以消除其严重的格式错误并引入所有可能的违规行为):

<t>
    <Company id="1" >
        <Name>blah</Name>
        <Location>
            <Address>zzz</Address>
            <City>aaa</City>
        </Location>
        <Manager id="m1" mincount="4" grade="10">
            <Employee id="e1"/>
            <Employee id="e2"/>
        </Manager>
    </Company>
    <Employee_List>
        <Employee id="e1" grade="11" Location="New York" p1="value" p2="value" />
        <Employee id="e2" grade="8" Location="Pittsburgh" p1="value" p2="value" />
    </Employee_List>
</t>

产生想要的正确结果

  Manager id = "m1" has too few employees.


  Manager id = "m1" has employees with higher grade than his own.


  Manager id = "m1" has employees at different locations.

【讨论】:

  • @FooBar:很高兴我的回答对您有所帮助。请您接受它(通过单击答案旁边的复选标记)吗?
  • Dimitre:完成。还添加/编辑了原始问题以验证更多属性。
猜你喜欢
  • 2012-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-11
  • 1970-01-01
  • 2017-05-31
相关资源
最近更新 更多